typeof 以及 instanceof
使用 typeof 以及 instanceof 关键词判断的方式也可以收敛类型。
function strOrNum(input: string | number) {
if (typeof input === 'string') {
// input is string now
} else {
// input is number
}
}
真值法(Truthiness)和判等法(equality)
declare const obj: Record<string, unknown> | null;
declare const bool1: boolean | undefined;
declare const bool2: boolean | null;
// if (obj) 那 obj 肯定不是 null 了
if (obj) {
// obj: Record<string, unknown>
} else {
// obj: null
}
// if (bool1 === bool2) 那 bool1 不可能是 undefined,因为 undefined 类型的变量永远不会等于 boolean,也永远不会等于 null;同样地,bool2 只能是 boolean
if (bool1 === bool2) {
// bool1: boolean
// bool2: boolean
}
in
in
判断某属性或者方法是否在对象中
type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
if ('swim' in animal) {
return animal.swim();
}
return animal.fly();
}
as
as
直接告诉 typescript 某对象是什么类型
declare const str: any;
let res = (str as string).toUpperCase();
declare const num: number;
let res2 = (num as unknown as string).toLowerCase();
// 不能直接收敛的情况下,要先断言为更宽泛的类型,如 unknown
自定义类型守卫函数
可以通过自己实现类型守卫函数来将类型收敛性。类型守卫比 typeof 更加强大了。
type Fish = { swim: () => void };
type Bird = { fly: () => void };
declare function getSmallPet(): Fish | Bird;
// 自定义类型守卫函数
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
let pet = getSmallPet();
if (isFish(pet)) {
// pet类型被收敛到了类型 Fish 上
pet.swim();
} else {
pet.fly();
}
断言函数 assert functions
断言函数:如果类型不符合所预期的,会报错
Node.js 有一个专门的断言函数assert
。
function multiply(x: any, y: any) {
assert(typeof x === 'number');
assert(typeof y === 'number');
// both x and y is number now
return x * y;
}
也可以自定义实现 assert 函数
法一
function myAssert(param: any, msg?: string): asserts param {
if (!param) {
throw new Error(msg);
}
}
function multiply(x: any, y: any) {
myAssert(typeof x === 'number');
myAssert(typeof y === 'number');
// both x and y is number now
return x * y;
}
法二
declare function isOdd(param: unknown): asserts param is 1 | 3 | 5;
function num(input: number) {
isOdd(input);
console.log(input);
// input is 1 | 3 | 5
}
! 后缀
!
可以从排除掉 null 和 undefined
declare const obj: { name: string } | null;
const name = obj!.name; // obj被断言为了 {name: string}
考虑到 type 安全,尽量不要用这个标识符。