文章目录
类型推断
如果没有明确的指定类型,TypeScript 会依照类型推断( Type Inference )的规则推断出一个类型,隐式设置类型注解。这种推断发生在初始化变量,决定函数返回值时。换句话说,由于类型推断的存在,这些情况,类型注解可以省略不写!
注意:对于开发者没有指定类型、TypeScript 必须自己推断类型的那些变量,如果无法推断出类型,TypeScript 就会认为该变量的类型是 any 。
// 声明变量并立即初始化值,此时,可以省略类型注解
let age = 18
// 注意:如果声明变量但没有立即初始化值,此时,还必须手动添加类型注解
let a: number
如果不知道类型,可以将鼠标悬停在变量名称上,利用 VSCode 的提示来查看类型。
场景一:初始化变量
let x = [0, 1, null];
x = [0, 1, 'a'];
场景二:决定函数返回值
函数参数若不设置类型注解也会隐式设置 any 类型,不过会报错。
function add(num1: number, num2: number) {
return num1 + num2
}
类型断言
TypeScript 提供了“类型断言”这样一种手段,允许开发者在代码中指定(断言)某个值的类型,告诉编译器此处的值是什么类型。
TypeScript 一旦发现存在类型断言,就不再对该值进行类型推断,而是直接采用断言给出的类型。
这样虽然削弱了 TypeScript 类型系统的严格性,但是为开发者带来了方便,毕竟开发者比编译器更了解自己的代码。
语法格式:<类型>值 或 值 as 类型
案例
getElementById 方法返回值的类型是 HTMLElement,该类型只包含所有标签公共的属性或方法,不包含 a 标签特有的 href 等属性。
const aLink = document.getElementById('link');
console.log(aLink.href);
解决办法:通过类型断言,将 aLink 的类型变为一个更加具体的类型(HTMLAnchorElement 是 HTMLElement 的子类型),这样就可以访问 a 标签特有的属性或方法了。
技巧:通过 console.dir(aLink) 打印 DOM 元素,在属性列表的最后面,即可看到该元素的类型。
语法一:值 as 类型
const aLink = document.getElementById('link') as HTMLAnchorElement;
console.log(aLink.href); // http://www.baidu.com/
语法二:<类型>值
const aLink = <HTMLAnchorElement>document.getElementById('link');
console.log(aLink.href); // http://www.baidu.com/
【非空断言】
对于那些可能为空的变量(即可能等于 undefined 或 null ),TypeScript 提供了非空断言,保证这些变量不会为空,变量名后面加上感叹号( ! )即可。
注意:非空断言只有在设置 "strictNullChecks": true 时才有意义。如果不打开这个选项,编译器就不会检查变量是否可能为 undefined 或 null 。
{
"compilerOptions": {
"strictNullChecks": true,
},
}
function f(x: number | null) {
console.log(x.toFixed()); // 由于“x”可能为 “null” 出现报错
}
f(2);
例1:上面示例中,形参 x 为必传参数,因其类型注解为 number | null ,编译器识别x可能为null于是报错,这时就可以使用非空断言,为函数体内部的变量 x 加上后缀( ! ),x!.toFixed() 编译就不会报错了。
function f(x: number | null) {
console.log(x!.toFixed()); // 正确
}
f(2);
例2:在定义类属性时,若配置 "strictPropertyInitialization": true(默认),则要求类的属性必须初始化(即有初始值),如果不对属性赋值就会报错。
{
"compilerOptions": {
"strictPropertyInitialization": true,
},
}
如果不希望出现报错,可以使用非空断言( ! )。
class Point {
x: number; // 报错
y: number; // 报错
}
class Point {
x!: number; // 正确
y!: number; // 正确
}