Open3
型のメモ
Union なオブジェクトからキーを抜きたい
普通にやったらうまく抜けなかった
以下のように調整したら取れた
type KeysOfUnion<T> = T extends T ? keyof T : never;
// 例
type A = {
description: any,
content: any
} | {
description: any,
$ref: any
},
type ResultA = KeysOfUnion<A> // "description" | "content" | "$ref"
Union なオブジェクトで keyof
すると、never
になってしまうため、KeysOfUnion
をかませる
KeysOfUnion
はジェネリクスの全てのUnion型に対して keyof T を適用することで、すべてのキーを取り出す型となります
オブジェクトがネストしている場合は以下のようにすることで型を抽出できます
type KeysOfUnion<T> = T extends T ? keyof T : never;
type KeysOfUnionObject<T> = T extends Record<string, infer U> ? KeysOfUnion<U> : never;
// 例
type A = {
200: {
description: any,
content: any
},
400: {
description: any,
content: any
},
401: {
$ref: any
},
403: {
description: any,
},
500: {
$ref: any
},
}
type ResultA = KeysOfUnionObject<A> // "description" | "content" | "$ref"
String か Union か判定するユーティリティ型
// `T` がユニオン型なら true、単一の `string` 型なら false を返す型
type IsUnion<T> = T extends string
? (string extends T ? false : true)
: false;
// `T` が単一の `string` 型なら true、ユニオン型なら false を返す型
type IsString<T> = T extends string
? (string extends T ? true : false)
: false;
- A は string に含まれるか
- string に A は含まれるか
という2回の判定を用いて union と string の判別を行う
never な parameter をオプショナルにする
型パズルする時に便利な型。以下のような流れで変換する。
- never な型の key を抽出
- 抽出した key を omit
- omit した key をオプショナルで再追加
/**valueがneverのキーを抽出する */
type NeverKey<T> = {[K in keyof T]: T[K] extends never ? K : never}[keyof T]
/**neverを持つパラメータをオプショナルにする */
type OptionalizeNeverParameters<T> = Omit<T, NeverKey<T>> & {
[key in NeverKey<T>]?: never
}
type Sample = { a: string, b: never };
const before: Sample = {
a: "1234",
// error: 'b' is declared here.
}
const after: OptionalizeNeverParameters<Sample> = {
a: "1234",
}