オブジェクトからstring
型のプロパティだけ取り出したいってことありませんか。僕はあります。何言ってんだという感じですがこういう感じです。
type EnumString = "foo" | "bar" | "piyo"; interface Mixed { a: string, b: number, c: object, d: EnumString }; type NoneStringKeys<T> = { [P in keyof T]: T[P] extends string ? never : P; }[keyof T]; type OnlyStringKeys<T> = { [P in keyof T]: T[P] extends string ? P : never; }[keyof T]; type OmitString<T> = Pick<T, Extract<keyof T, NoneStringKeys<T>>>; type OnlyString<T> = Pick<T, Extract<keyof T, OnlyStringKeys<T>>>; const Y: OmitString<Mixed> = { b: 1, c: {} } const X: OnlyString<Mixed> = { a: "", d: "foo" }
いったんKeyを生成して,その後でPickとExtractを使っています。かっこいいですね。これが型だけで、コンパイルタイミングでできるのすごいですね。
順を追って見ていくと、まずオブジェクト中にある特定の型のプロパティ名だけを取り出すような型コンストラクタを定義し、それを使って実際にプロパティをフィルタしています。
NoneStringKeys
とOnlyStringKeys
がミソで、三項演算子が型にも適用できるのってすごいですよね。never
型にすることで型を消すというテクニックがおもしろいと感じました。
というのも、never
とのunion型はnever
型がちょうど消えてしまうんですね。
A | never
=> A