TypeScript 練習 オブジェクトの文字列の値をstringのリテラルとして取得する
以下のようなオブジェクトがあるとします。
const actions = {
user: {
update: "USER_UPDATE",
remove: "USER_REMOVE",
admin: {
update: "USER_ADMIN_UPDATE"
},
invalid:9999
},
mail: {
create: 'MAIL_CREATE'
},
reset: "RESET_ALL"
}
このオブジェクトから、以下のような型を取得することを目標にします。
type MyType = "USER_UPDATE" | "USER_REMOVE" | "USER_ADMIN_UPDATE" | 'MAIL_CREATE' | "RESET_ALL"
どこかで見覚えがありますが、そう、Redux の Action です。
まずは actions から型を取得するために const アサーションをつけます。
const actions = {
user: {
update: "USER_UPDATE",
remove: "USER_REMOVE",
admin: {
update: "USER_ADMIN_UPDATE"
},
invalid:9999
},
mail: {
create: 'MAIL_CREATE'
},
reset: "RESET_ALL"
} as const
これで typeof を使うことで actions を型にできます。
type Actions = typeof actions
続いて、オブジェクト型のstringである文字列だけを再帰的に取得してUNIONにする型をつくります。
type MakeActionsUnion<T extends Record<string, unknown>> = {
[K in keyof T]: T[K] extends string ? T[K] : T[K] extends Record<string, unknown> ? T2<T[K]> : never
}[keyof T]
あとはこのT1を使って、Actions から文字列のUNIONを作り出します。
type ActionsUnion = MakeActionsUnion<Actions>
実際に想定した動きになるか見ます。
const a: ActionsUnion = "USER_UPDATE" //OK
const b: ActionsUnion = "USER_ADMIN_UPDATE" //OK
const c: ActionsUnion = 9999 //NG
const d: ActionsUnion = "MAIL_CREATE" //OK
const e: ActionsUnion = "RESET_ALL" //OK
const f: ActionsUnion = "hogehoge" //NG
最近のコメント