TypeScript常见类型

最近看了一些ts的语法,觉得有点陌生,经过一番搜索发现之前看的中文文档版本落后了很多。。。嗨,现在对着英文文档再回顾一下吧

基本数据类型

string、number、boolean

类型名 String ,Number 和 Boolean (首字母大写)也是合法的,但它们是一些非常少见的特殊内置类型。所以类型总是使用 string ,number 或者 boolean 。

数组

声明方式:number[]Array<number>。在jsx语法中只能使用前者

any

当不指定类型时,并且ts无法从上下文中推断出该类型时,编译器通常会默认为any

变量的类型注释

指声明变量时指定该变量的类型,例如let a:string = '字符串'

函数

ts允许指定函数输入和输出值的类型
通过参数类型注解指定输入类型,通过函数返回类型注解指定函数返回值类型

1
2
3
function getString(str:string):string{
return str;
}

匿名函数

当一个函数出现在 TypeScript 可以确定如何调用它的地方时,该函数的参数会自动被赋予类型
这个过程称为上下文类型,因为函数发生的上下文告知它应该具有什么类型,例如foreach中的callback函数

对象类型

只需列出其属性和类型

可选属性

在属性后面加?表明该属性可选
当从可选属性中读取属性时,需要先判断不是undefined

联合类型

通过|定义,表明该类型是指定类型的其中之一
但在访问属性时,仅允许访问二者属性的交集。

1
2
3
4
5
function printId(id: number | string) {
console.log(id.toUpperCase());
//Property 'toUpperCase' does not exist on type 'string | number'.
//Property 'toUpperCase' does not exist on type 'number'.
}

需要我们收窄范围,即通过条件语句判断类型,再访问属性

别名类型

指type,不仅能为对象类型使用,任何类型都能使用。例如type ID = number | string;

别名 只是 别名,不能使用类型别名创建同一类型的不同“版本”

接口

接口声明 是命名对象类型的另一种方式

类型别名和接口之间的区别
类型别名和接口非常相似,在大多数情况下你可以在它们之间自由选择。 几乎所有的 interface 功能都可以在 type 中使用,关键区别在于不能重新开放类型以添加新的属性,而接口始终是可扩展的

interface type
扩展接口 通过extends关键字继承接口 通过&扩展类型
添加新字段 重新声明接口直接写 无法添加
  • 在 TypeScript 4.2 之前,类型别名命名 可能 会出现在错误消息中,有时代替等效的匿名类型(可能需要也可能不需要)。接口在错误消息中将始终被命名。
  • 类型别名不能参与 声明合并,但接口可以。
  • 接口只能用于 声明对象的形状,不能重命名基本类型.
  • 接口名称将 始终 以其原始形式出现 在错误消息中,但 只有 在按名称使用时才会出现。

类型断言

有时你会得到关于 TypeScript 无法知道的值类型的信息。

例如,如果您正在使用document.getElementById,TypeScript 只知道这将返回某种,HTMLElement但您可能知道您的页面将始终具有HTMLCanvasElement具有给定 ID 的 。

通过as或<>断言(jsx语法中只能用前者)

1
2
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas");

TypeScript 只允许类型断言转换为更具体或更不具体的类型版本。此规则可防止“不可能”的强制,例如将string类型断言为number时,会报错
但是可以通过连用as实现上述操作:

1
const a = expr as any as T;

文字类型

声明一个变量让其等于指定值。
let x: "hello" = "hello";
可以通过联合类型组合文字类型,使其只接受一组值中的一个

1
2
3
4
5
6
function printText(s: string, alignment: "left" | "right" | "center") {
// ...
}
printText("Hello, world", "left");
printText("G'day, mate", "centre");
// Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.

boolean本身也是union的别名,true|false

字面推理

当使用对象初始化变量时,TypeScript 假定该对象的属性可能会在以后更改值

有两种方法可以解决这个问题

  1. 通过在任一位置添加类型断言来更改推理
    1
    2
    3
    4
    // Change 1:
    const req = { url: "https://example.com", method: "GET" as "GET" };
    // Change 2
    handleRequest(req.url, req.method as "GET");
    更改 1 的意思是“我打算req.method始终拥有文字类型 “GET””,从而防止之后可能分配”GUESS”给该字段。
    更改 2 的意思是“我知道有其他req.method价值的原因”GET””。
  2. as const将整个对象转换为类型文字:
1
2
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);

as const 后缀的作用类似于 const,但用于类型系统,确保为所有属性分配文字类型,而不是更通用的版本,如字符串或数字。

null 和 undefined

JavaScript 有两个原始值用于表示不存在或未初始化的值:null和undefined.

当strictNullChecks关闭的时候,等于是对null和undefined没有检查
打开时,当一个值为null或undefined时,您需要在对该值使用方法或属性之前测试这些值。就像undefined在使用可选属性之前检查一样,我们可以使用缩小来检查可能是的值null

非空断言运算符 !

通过再表达式后面写!来表示该值不是null或undefined

两个感叹号!!表示 一个狭窄的文字布尔类型 true
!!"world"; // type: true, value: true

作者

徐云飞

发布于

2022-09-07

更新于

2023-02-05

许可协议

评论