• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

TypeScript类型注解、类型推断和类型断言

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

一、类型注解(Type annotation)

所谓类型注解,就是人为为一个变量指定类型,例如:

const a: number = 123;

在 vscode 中鼠标移入 a 出现提示,冒号后面就是类型注解:

当不添加类型注解时,TypesScript 也能知道变量 a 是一个数字,这就是 TypeScript 的类型推断:

 

二、类型推断(Type inference)

所谓类型推断就是 TypeScript 可以通过变量值倒推变量类型,因此在绝大部分情况下,我们是不需要去写类型注解的

但有些情况类型推断是无法推断变量类型的,例如函数的参数:

function getSum(a, b) {
  return a + b;
}
const num = getSum(1, 2);

上面代码中的参数 a,b 就无法类型:

从而也导致了 num 的类型不能判断:

这时就需要类型注解来为参数指定类型:

function getSum(a: number, b: number) {
  return a + b;
}
const num = getSum(1, 2);

这样 num 就可以推断出类型了:

 

三、类型断言(Type Assertion)

TypeScript 允许你覆盖它的推断,以你想要的方式分析它并手动的指定一个值的类型,这种机制被称为类型断言

类型断言用来告诉编译器你比它更了解这个类型,并且它不应该再发出错误

常见用例:

const foo = {};
foo.bar = 123;     // Error: 'bar' 属性不存在于 ‘{}’
foo.bas = 'hello';  // Error: 'bas' 属性不存在于 '{}'

这里报错是因为 foo 的类型推断为 {}(即具有零属性的对象)

因此,无法在它的属性上添加 bar 或 bas,这时就可以通过类型断言来解决:

interface Foo {
  bar: number;
  bas: string;
}

const foo = {} as Foo;
foo.bar = 123;
foo.bas = 'hello';

 

1、as foo 与 <foo>

最初的断言语法如下:

let foo: any;
let bar = <string>foo;  // 现在 bar 的类型是 'string'

然而,当你在 JSX 中使用 <foo> 的断言语法时,会与 JSX 的语法存在歧义:

let foo = <string>bar;</string>;

因此,为了一致性,建议使用 as foo 的语法来为类型断言

 

2、类型断言与类型转换

之所以不被称为「类型转换」,是因为转换通常意味着某种运行时的支持

但类型断言纯粹是一个编译时语法,同时也是一种为编译器提供关于如何分析代码的方法

 

3、类型断言被认为是有害的

大部分情况下,断言能让你更容易的从遗留项目中迁移

然而,如果没有按约定添加属性,TypeScript 编译器并不会对以下情况发出错误警告:

interface Foo {
  bar: number;
  bas: string;
}

const foo = {} as Foo;

// 忘记添加上面例子的属性

另一个常见的用法是使用类型断言来提供代码的提示:

interface Foo {
  bar: number;
  bas: string;
}

const foo = <Foo>{
  // 编译器将会提供关于 Foo 属性的代码提示
  // 但是开发人员也很容易忘记添加所有的属性
  // 同样,如果 Foo 被重构,这段代码也可能被破坏(例如,一个新的属性被添加)。
};

这也会存在一个同样的问题,如果忘记了某个属性,编译器也不会报错

使用一种更好的方式:

interface Foo {
  bar: number;
  bas: string;
}

const foo: Foo = {
  // 编译器将会提供 Foo 属性的代码提示
};

当需要创建一个临时变量时,一般不会使用断言,而是依靠类型推断来检查代码

 

4、双重断言

当使用者了解传入参数更具体的类型时,类型断言能按预期工作:

function handler(event: Event) {
  const mouseEvent = event as MouseEvent;
}

然而,下面例子中的代码将会报错,尽管使用者已经使用了类型断言:

function handler(event: Event) {
  const element = event as HTMLElement; // Error: 'Event' 和 'HTMLElement' 中的任何一个都不能赋值给另外一个
}

如果仍想使用那个类型,可以使用双重断言

先断言成兼容所有类型的 any,再断言成想使用的类型:

function handler(event: Event) {
  const element = (event as any) as HTMLElement; // ok
}

 


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
TypeScript类型注解,类型推断发布时间:2022-07-18
下一篇:
TypeScript(入门)发布时间:2022-07-18
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap