TS高级用法总结《二》
本文主要内容:typeof、条件类型
本文阅读时间大约为6分钟,请听笔者娓娓道来。
typeof 类型运算符
请注意 type 是类型别名
// Prints "string"
console.log(typeof "Hello world");
使用 typeof 会自动返回 类型,这对于基本类型并不十分有用,但是结合其他类型操作符,您可以使用 typeof 方便地表示许多模式。
function f() {
return { x: 10, y: 3 };
}
type P = ReturnType<typeof f>;
// type P = {
// x: number;
// y: number;
// }
或者还可以通过 索引
type Person = { age: number; name: string; alive: boolean };
type Age = Person["age"];
// type Age = number
使用任意类型进行索引的另一个示例是使用 T 来获取数组元素的类型。我们可以把它和 typeof 结合起来,方便地捕获数组文字的元素类型:
const MyArray = [
{ name: "Alice", age: 15 },
{ name: "Bob", age: 23 },
{ name: "Eve", age: 38 },
];
type Person = typeof MyArray[T];
// type Person = {
// name: string;
// age: number;
// }
type Age = typeof MyArray[T]["age"];
// type Age = number
// Or
type Age2 = Person["age"];
// type Age2 = number
条件类型
在大多数有用的程序的核心,我们必须根据输入做出决定。程序没有什么不同,但是考虑到值可以很容易地反省,这些决定也是基于输入的类型。条件类型帮助描述输入和输出类型之间的关系。
interface Animal {
live(): void;
}
interface Dog extends Animal {
woof(): void;
}
type Example1 = Dog extends Animal ? number : string;
// Dog 是继承自 Animal
// type Example1 = number
type Example2 = RegExp extends Animal ? number : string;
// type Example2 = string
再如有个重载函数,看看咱么怎么通过这个条件类型去改写。createLabel 的重载描述了一个基于输入类型进行选择的 JavaScript 函数
interface IdLabel {
id: number /* some fields */;
}
interface NameLabel {
name: string /* other fields */;
}
function createLabel(id: number): IdLabel;
function createLabel(name: string): NameLabel;
function createLabel(nameOrId: string | number): IdLabel | NameLabel;
function createLabel(nameOrId: string | number): IdLabel | NameLabel {
throw "unimplemented";
}
改写
type NameOrId<T extends number | string> = T extends number
? IdLabel
: NameLabel;
// 我们可以使用该条件类型将重载简化为单个函数,而不需要重载
function createLabel<T extends number | string>(idOrName: T): NameOrId<T> {
throw "unimplemented";
}
let a = createLabel("typescript");
// let a: NameLabel
let b = createLabel(2.8);
// let b: IdLabel
let c = createLabel(Math.random() ? "hello" : 42);
// let c: NameLabel | IdLabel
总结
条件类型这一部分,还有一些更高级的用法,但笔者认为,可以先把这篇文章的内容学懂,再去学更高级的。虽然平常可能用不到,但是当你阅读源码的时候,你就会体会类型约束带来的好处!
阅读 Vue3 源码,如果不知道 ts 的高级用法,你可能会别绕晕;但是,如果你是初次阅读源码,建议在社区内找一个“简单”版本学习,咳咳!
👍👍👍
推荐源码阅读从 mini-vue 开始:gitHub 仓库,实现了最简的 Vue 模型!