Skip to content

Instantly share code, notes, and snippets.

@wonderful-panda
Last active July 13, 2018 03:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wonderful-panda/3156681f25ee72e1a3bfbeaf3764288b to your computer and use it in GitHub Desktop.
Save wonderful-panda/3156681f25ee72e1a3bfbeaf3764288b to your computer and use it in GitHub Desktop.
Vue Component の PropsDefinitionからpropsの型をrequired/optional付きで導出するやつ
import { RecordPropsDefinition } from "vue/types/options";
// Propsの定義から、required指定されたprop名を抽出する
// const a = { foo: String, bar: { type: String, required: true as true }, baz: { type: String, required: false } }; の時、
// RequiredPropNames<typeof a> は "bar"
export type RequiredPropNames<PD extends RecordPropsDefinition<any>> = ({
[K in keyof PD]: PD[K] extends { required: true } ? K : never
})[keyof PD];
// Propsの定義から、required指定されていないprop名を抽出する
// const a = { foo: String, bar: { type: String, required: true as true }, baz: { type: String, required: false } }; の時、
// OptionalPropNames<typeof a> は "foo" | "baz"
export type OptionalPropNames<PD extends RecordPropsDefinition<any>> = {
[K in keyof PD]: PD[K] extends { required: true } ? never : K
}[keyof PD];
// Propsの定義から、外部公開用のPropsの型を導出する
// const a = { foo: String, bar: { type: String, required: true as true }, baz: { type: String, required: false } }; の時、
// OuterProps<typeof a> は { foo?: string | undefined, bar: string, baz?: string | undefined }
export type OuterProps<
PropDefs extends RecordPropsDefinition<any>
> = PropDefs extends RecordPropsDefinition<infer P>
? { [K in RequiredPropNames<PropDefs> & keyof P]: P[K] } &
{ [K in OptionalPropNames<PropDefs> & keyof P]?: P[K] }
: never;
const props = {
foo: String,
bar: { type: String, required: true as true }, // true as true って書かないとダメなのが悲しいところ
baz: { type: String, required: false }
};
// { foo?: string | undefined, bar: string, baz?: string | undefined }
type Props = OuterProps<typeof props>;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment