类型断言
类型断言用于清楚地知道一个实体具有比它现有类型更确切的类型,其实就是在使用时(而非定义时)手动指定变量类型。
- 类型断言的作用是使typescript假设已经进行了类型检查
- 类型断言类似其他语言里的类型转换,但是不进行特殊的类型转换和解构
- 只在编译阶段起作用,没有运行时的影响
两种形式的语法:尖括号语法与as语法
//尖括号语法
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
//as语法
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
类型推论
类型推论的含义就是“类型是在哪里如何被推断的”, 主要作用是“在有些没有明确指出类型的地方帮助确定与提供类型“
最佳通用类型
最佳通用类型,顾名思义,就是对于某些表达式的最合适的通用类型
计算通用类型的算法会考虑所有的候选类型,并给出一个兼容所有候选类型的类型。
let x = 3; // => number
let y = [0, 1, 2];
let z = [1, 's', null]; // (number|string|null)[]
z[3] = 'ss';
z[4] = false
let zoo: Animal[] = [new Rhino(), new Elephant(), new Snake()];
如果没有找到最佳通用类型,则类型推断的结果为联合数组类型(因为此时变量一定是多种类型的集合)。比如上面的zoo,如果没有指定Animal[]类型,则推断结果为(Rhino | Elephant | Snake)[]
上下文类型
上下文类型推论是反方向进行TypeScript类型推论(个人理解:从变量类型推断值或者参数的类型),被叫做“按上下文归类”,会发生在表达式的类型与所处的位置相关时,通常包含函数的参数,赋值表达式的右边,类型断言,对象成员和数组字面量和返回值语句
window.onmousedown = function(mouseEvent) {
console.log(mouseEvent.button);
};
此时函数表达式处在上下文类型的位置,TypeScript类型检查器使用Window.onmousedown函数的类型来推断右边函数表达式的类型。 因此,就能推断出 mouseEvent参数的类型了(也就是MouseEvent类型)
上下文类型也会做为最佳通用类型的候选类型
区分类型与类型保护
对于是联合类型的变量,如何确切的知道是哪一种类型呢?javascript中常用的方式是检查成员是否存在,但是typescript中联合类型只能访问联合类型中共同拥有的成员。
可是通过类型断言来进行类型判断,但是有个问题就是每个分支都需要进行类型判断
typescript的类型保护机制: 一次判断,整个作用域/所有分支有效。
类型保护就是一些表达式,它们会在运行时检查以确保在某个作用域里的类型
typeof类型保护
typeof类型保护用来判断变量是哪种原始类型。
有两种形式: typeof v === "typename" typeof v !== "typename"
"typename"必须是 "number", "string", "boolean"或 "symbol",也可以与其它字符串比较,但是typescript不会把那些表达式识别为类型保护
instanceof 类型保护
instanceof类型保护是通过构造函数来细化类型,其右侧要求是一个构造函数,TypeScript将细化为:
- 此构造函数的 prototype属性的类型,如果它的类型不为 any的话
- 构造签名所返回的类型的联合
自定义类型保护
首先解释一个名词: 类型谓词。 类型谓词为 parameterName is Type这种形式, parameterName必须是来自于当前函数签名里的一个参数名。
定义一个类型保护,只要简单地定义一个函数,其返回值是一个 类型谓词
function isFish(pet: Fish | Bird): pet is Fish {
return (<Fish>pet).swim !== undefined;
}
if (isFish(pet)) {
pet.swim();
} else {
pet.fly();
}
使用变量来调用自定义类型保护时,TypeScript会将变量缩减为那个具体的类型,只要这个类型与变量的原始类型是兼容的。