type-challenges 中級編12: StartsWith、EndsWith、PartialByKeys
はじめに
GitHubのtype-challengesリポジトリは、TypeScript型システムの理解を深めるための型クイズ問題集です。高品質な型を作成することで、バグを減らし、プロジェクトの保守性を向上させることができます。今回も中級編から3つの問題に挑戦します。
1. StartsWith
この課題では、2つの文字列型 T
と U
を受け取り、T
が U
で始まるかどうかを判定する型を実装します。
例
type a = StartsWith<'abc', 'ac'> // expected to be false
type b = StartsWith<'abc', 'ab'> // expected to be true
type c = StartsWith<'abc', 'abcd'> // expected to be false
私の回答
type StartsWith<T extends string, U extends string> =
T extends `${U}${infer Rest}` ? true : false
解き方
- テンプレートリテラル型を使用して、文字列
T
がU
で始まるかどうかを判定します。 -
T
が${U}${infer Rest}
に一致する場合、T
はU
で始まることを意味し、true
を返します。それ以外の場合はfalse
を返します。
文字列リテラルで型を推定してあげれば簡単ですね。
2. EndsWith
この課題では、2つの文字列型 T
と U
を受け取り、T
が U
で終わるかどうかを判定する型を実装します。
例
type a = EndsWith<'abc', 'bc'> // expected to be true
type b = EndsWith<'abc', 'abc'> // expected to be true
type c = EndsWith<'abc', 'd'> // expected to be false
私の回答
type EndsWith<T extends string, U extends string> =
T extends `${infer Rest}${U}` ? true : false
解き方
- テンプレートリテラル型を使用して、文字列
T
がU
で終わるかどうかを判定します。 -
T
が${infer Rest}${U}
に一致する場合、T
はU
で終わることを意味し、true
を返します。それ以外の場合はfalse
を返します。
StartWithと一緒!
3. PartialByKeys
この課題では、ジェネリック型 T
と K
を受け取り、K
に指定されたプロパティのみをオプショナルにする型を実装します。K
が指定されていない場合は、全てのプロパティをオプショナルにします。
例
interface User {
name: string
age: number
address: string
}
type UserPartialName = PartialByKeys<User, 'name'> // { name?:string; age:number; address:string }
私の回答
type MergeObj<T> = {
[k in keyof T]: T[k]
}
type PartialByKeys<T, K = keyof T> = MergeObj<{
[k in keyof T as k extends K ? never : k]: T[k]
} & {
[k in keyof T as k extends K ? k : never]?: T[k]
}>
解き方
-
PartialByKeys
は、まずK
に指定されたプロパティを除外したオブジェクト型を生成し、次にK
に指定されたプロパティのみをオプショナルにしたオブジェクト型を生成します。 - 最後にこれらのオブジェクト型をマージして、指定されたプロパティのみがオプショナルになるようにします。
{
[k in keyof T]: T[k]
}
パターンの応用でした。
type a = {
xxx: aaa
}&
{
yyy: bbb
}
は
type MergeObj<T> = {
[k in keyof T]: T[k]
}
で
type a = {
xxx: aaa
yyy: bbb
}
にできることも覚えておきましょう
まとめ
これらの課題を通じて、TypeScriptの型システムをより深く理解することができます。特にテンプレートリテラル型や再帰的な型の使用法について学ぶことで、より柔軟で強力な型を作成するスキルが身につきます。ぜひこれらの課題に挑戦して、型の理解を深めてください。