Skip to content

Utility Types

INFO

This page only lists a few commonly used utility types that may need explanation for their usage. For a full list of exported types, consult the source code.

PropType<T>

Used to annotate a prop with more advanced types when using runtime props declarations.

  • Example

    ts
    import type { PropType } from 'vue'
    
    interface Book {
      title: string
      author: string
      year: number
    }
    
    export default {
      props: {
        book: {
          // provide more specific type to `Object`
          type: Object as PropType<Book>,
          required: true
        }
      }
    }
  • See also Guide - Typing Component Props

MaybeRef<T>

Alias for T | Ref<T>. Useful for annotating arguments of Composables.

  • Only supported in 3.3+.

MaybeRefOrGetter<T>

Alias for T | Ref<T> | (() => T). Useful for annotating arguments of Composables.

  • Only supported in 3.3+.

ExtractPropTypes<T>

Extract prop types from a runtime props options object. The extracted types are internal facing - i.e. the resolved props received by the component. This means boolean props and props with default values are always defined, even if they are not required.

To extract public facing props, i.e. props that the parent is allowed to pass, use ExtractPublicPropTypes.

  • Example

    ts
    const propsOptions = {
      foo: String,
      bar: Boolean,
      baz: {
        type: Number,
        required: true
      },
      qux: {
        type: Number,
        default: 1
      }
    } as const
    
    type Props = ExtractPropTypes<typeof propsOptions>
    // {
    //   foo?: string,
    //   bar: boolean,
    //   baz: number,
    //   qux: number
    // }

ExtractPublicPropTypes<T>

Extract prop types from a runtime props options object. The extracted types are public facing - i.e. the props that the parent is allowed to pass.

  • Example

    ts
    const propsOptions = {
      foo: String,
      bar: Boolean,
      baz: {
        type: Number,
        required: true
      },
      qux: {
        type: Number,
        default: 1
      }
    } as const
    
    type Props = ExtractPublicPropTypes<typeof propsOptions>
    // {
    //   foo?: string,
    //   bar?: boolean,
    //   baz: number,
    //   qux?: number
    // }

ComponentInstance

Used to extract the instance type of a component (equivalent to the type of this in its options).

  • Example
vue
<script setup lang="ts">
import { ComponentInstance } from 'vue'
import Foo from './Foo.vue'

const fooEl = ref<null | ComponentInstance<typeof Foo>>(null)
</script>
<template>
  <Foo ref="fooEl" />
</template>

ComponentCustomProperties

Used to augment the component instance type to support custom global properties.

ComponentCustomOptions

Used to augment the component options type to support custom options.

  • Example

    ts
    import { Route } from 'vue-router'
    
    declare module 'vue' {
      interface ComponentCustomOptions {
        beforeRouteEnter?(to: any, from: any, next: () => void): void
      }
    }

    TIP

    Augmentations must be placed in a module .ts or .d.ts file. See Type Augmentation Placement for more details.

  • See also Guide - Augmenting Custom Options

ComponentCustomProps

Used to augment allowed TSX props in order to use non-declared props on TSX elements.

  • Example

    ts
    declare module 'vue' {
      interface ComponentCustomProps {
        hello?: string
      }
    }
    
    export {}
    tsx
    // now works even if hello is not a declared prop
    <MyComponent hello="world" />

    TIP

    Augmentations must be placed in a module .ts or .d.ts file. See Type Augmentation Placement for more details.

CSSProperties

Used to augment allowed values in style property bindings.

  • Example

    Allow any custom CSS property

    ts
    declare module 'vue' {
      interface CSSProperties {
        [key: `--${string}`]: string
      }
    }
    tsx
    <div style={ { '--bg-color': 'blue' } }>
    html
    <div :style="{ '--bg-color': 'blue' }"></div>

TIP

Augmentations must be placed in a module .ts or .d.ts file. See Type Augmentation Placement for more details.

See also

SFC <style> tags support linking CSS values to dynamic component state using the v-bind CSS function. This allows for custom properties without type augmentation.

DeclareComponent

More user friendly way to generate or extend DefineComponent type.

WARNING

Note that you must define the properties, using DeclareComponent is just typescript, it will fail at runtime.

  • Validator Example
ts
type Validator<T> = { value: T; validate(): boolean }
declare function generateComponent<
  T extends Record<string, Validator<any>>
>(schema: T): DeclareComponent<{ [K in keyof T]: T[K]['value'] }>

generateComponent({
  test: {
    value: 'test',
    validate: () => true
  }
}).props.test // { type: String, required: true}
  • HoC Example
ts
declare function extendAsHTMLElement<T extends DefineComponent>(
  options: T
): T & DeclareComponent<HTMLAttributes>

extendAsHTMLElement(
  defineComponent({
    setup:
      (_, { attrs }) =>
      () =>
        h('input', attrs)
  })
).props.about // { type: String, required: false}
  • Generic Example

You don't necessarily need to you DeclareComponent, but you can.

Is necessary to use new<...>{ $props: { ... } } for Generic components, using type helpers with Generic params might break generic types.

ts
type ErrorLevel = 'debug' | 'warning' | 'error'

declare function ErrorComponent<T>(options: T): T &
    new <T extends ErrorLevel = 'debug'>(): {
      $props: { type: T } & {
        [K in `on${Capitalize<T>}`]: (msg: string) => void
      }
      $slots: SlotsType<Record<T, (msg: string) => any[]>>
    }

const Comp = ErrorComponent(
  defineComponent({
    props: {
      type: {
        type: String as () => ErrorLevel,
        default: 'debug'
      }
    },
    emits: ['debug', 'warning', 'error']
  })
)
;<Comp type="debug" onDebug={() => {}} />
// @ts-expect-error onError is not there
;<Comp type="debug" onError={(v) => {}} />

ExtractComponentOptions<T>

Extracts component declared options.

ts
const Comp = defineComponent({
  props: {
    foo: String
  }
})
const options = {} as ExtractComponentOptions<typeof Comp>
options.props // { foo: StringConstructor }

ExtractComponentPropOptions<T>

Extracts the component props as the component was created, or the props from the ComponentPublicInstance.

ts
const Comp = defineComponent({
  props: {
    foo: String
  }
})
const props = {} as ExtractComponentPropOptions<typeof Comp>
props.foo // StringConstructor

ExtractComponentSlotOptions<T>

Extracts the component slots as the component was created.

ts
const Comp = defineComponent({
  slots: {} as SlotsType<{
    foo: (bar: string) => any
    baz: (bar: number) => any
  }>
})
const slots = {} as ExtractComponentSlotOptions<typeof Comp>
slots // SlotsType<{ foo: (bar: string) => any; baz: (bar: number) => any; }>

ExtractComponentEmitOptions<T>

Extracts the component emits as the component was created.

ts
const Comp = defineComponent({
  emits: {
    foo: (test: string) => true
  }
})
const emits = {} as ExtractComponentEmitOptions<typeof Comp>
emits.foo // (test: string) => true

ObjectToComponentProps<T>

Converts an Record<string, any> into a props definition like object.

Useful for extending component props.

ts
const props: ObjectToComponentProps<{ foo: 'bar' | 'baz', baz?: number }>
 // props is:
 {
   foo: {
    type: Prop<'bar' | 'baz'>,
    required: true
   },
   baz: {
    type: Prop<number>,
    required: false
   }
 }

ComponentEmitsAsProps<T>

Converts Emit declaration into props declaration, returned object will be optional.

ts
declare const emit: ComponentEmitsAsProps<{ emits: { foo: () => true } }>
emit.onFoo?.() // ok

ComponentProps<T>

Returns runtime props for a component.

ts
const Comp = defineComponent({
  props: {
    foo: String
  }
})
const props = {} as ComponentProps<typeof Comp>
props.foo // string | undefined

ComponentSlots<T>

Returns runtime slots for a component.

ts
const Comp = defineComponent({
  slots: {} as SlotsType<{
    default: (arg: { msg: string }) => any
  }>
})

const slots = {} as ComponentSlots<typeof Comp>
slots.default // { arg: { msg: string } } => any

ComponentEmit<T>

Returns the emit function from options.

ts
const CompSlotsTyped = defineComponent({
  emits: {
    foo: (arg: string) => true
  }
})

const emit = {} as ComponentEmit<typeof CompSlotsTyped>
emit // (event: 'foo', arg: string) => void

ComponentData<T>

Returns the component bindings from data and setup.

ts
const Comp = defineComponent({
  data() {
    return {
      foo: 'string'
    }
  },

  setup(props, ctx) {
    return {
      bar: 42
    }
  }
})

const data = {} as ComponentData<typeof Comp>
data.foo // string
data.bar // number

DefineComponentOptions & DefineComponentFromOptions

Allows to get vue component options and generate DefineComponent type.

WARNING

The generic order is not prone to change, but it might, Options should be the last generic used, new generics will be added before Options.

INFO

Note that you if you need to handle generics, it should be it's own overload, since any change to the Generic definition might break the Generic type.

ts
declare function defineComponentWithDefaults<
  Props = never,
  RawBindings = {},
  D = {},
  C extends ComputedOptions = {},
  M extends MethodOptions = {},
  Mixin extends ComponentOptionsMixin = ComponentOptionsMixin,
  Extends extends ComponentOptionsMixin = ComponentOptionsMixin,
  E extends EmitsOptions = {},
  EE extends string = string,
  I extends ComponentInjectOptions = {},
  II extends string = string,
  S extends SlotsType = {},
  Options extends {} = {}
>(
  options: DefineComponentOptions<
    Props,
    RawBindings,
    D,
    C,
    M,
    Mixin,
    Extends,
    E,
    EE,
    I,
    II,
    S,
    Options
  >,
  defaults: Partial<
    [Props] extends [string]
      ? { [K in Props]?: any }
      : ExtractPropTypes<Props>
  >
): DefineComponentFromOptions<
  undefined extends Props ? {} : Props,
  RawBindings,
  D,
  C,
  M,
  Mixin,
  Extends,
  E,
  EE,
  I,
  II,
  S,
  Options
>
Utility Types has loaded