面试题答案
一键面试1. 模板字面量类型新特性
- 类型字符串拼接:在TypeScript 4.0之前,无法在类型层面进行字符串拼接操作。4.0引入模板字面量类型后,可以像在JavaScript中拼接字符串一样在类型层面拼接字符串。例如:
type Prefix = 'hello';
type Suffix = 'world';
type NewString = `${Prefix}-${Suffix}`;
// NewString 类型为 'hello-world'
- 类型字符串替换:可以基于已有的类型字符串进行部分替换。例如:
type ReplaceString<Str extends string, From extends string, To extends string> =
Str extends `${infer Before}${From}${infer After}` ? `${Before}${To}${After}` : Str;
type result = ReplaceString<'hello world', 'world', 'typescript'>;
// result 类型为 'hello typescript'
2. 创建更强大的类型映射
- 利用模板字面量类型创建索引类型映射:
type Keys = 'a' | 'b' | 'c';
type ValueType = string;
type MappedType = {
[Key in Keys as `${Key}_suffix`]: ValueType;
};
// MappedType 类型为 { a_suffix: string; b_suffix: string; c_suffix: string; }
这里通过模板字面量类型 ${Key}_suffix
改变了索引类型的键名,使得生成的类型结构更符合特定需求。
3. 结合条件类型和模板字面量类型实现复杂类型转换
- 根据条件生成不同的类型字符串:
type IfString<T extends string, Then extends string, Else extends string> =
T extends string ? Then : Else;
type ConditionalString<T> = IfString<T, `${T}_is_string`, `${T}_is_not_string`>;
type stringResult = ConditionalString<'test'>;
// stringResult 类型为 'test_is_string'
type numberResult = ConditionalString<123>;
// numberResult 类型为 '123_is_not_string'
- 复杂类型转换示例 - 路径映射:假设我们有一个对象类型,想要根据对象的路径生成新的类型。
type Obj = {
a: {
b: {
c: string;
};
};
};
type PathToValue<Obj, Path extends string> =
Path extends `${infer Key}.${infer Rest}`
? Key extends keyof Obj
? PathToValue<Obj[Key], Rest>
: never
: Path extends keyof Obj
? Obj[Path]
: never;
type resultType = PathToValue<Obj, 'a.b.c'>;
// resultType 类型为 string
在这个例子中,通过条件类型和模板字面量类型,将路径字符串解析并映射到对象对应属性的类型上,实现了复杂的类型转换。