TypeScript 中文教程基础部分下----翻译自TS官方

🔯 type 别名

我们已经使用过 object 和 联合的方式 直接声明类型。但是某个类型在使用多次的情况下就要用到别名了。

别名的语法就像是在定义一个具名的对象一样:

type Point = {
  x: number;

  y: number;
}

function printCoord(pt: Point) {
  console.log(pt.x);

  console.log(pt.y);
}

printCoord({ x: 100,  y: 100 });

定义一个别名不仅仅可以是对象的形式,还可以是其他形式,比如联合类型

type ID = number | string;

别名仅仅只是个别名,你不能使用一个别名再去创建一个不同版本的别名但却表达同样的类型。如果你使用一个别名继续创建另一个别名,这件事就是一种重复劳动没有意义,即使能正常运行。

所以不要这样定义:

🤢 type userString = string

 

🔯 interfaces 接口 :是另一种用来声明 object type 的类型

interface Point {
  x: number;

  y: number;
}

用法不变

function printCoord(pt: Point) {
  console.log(pt.x);

  console.log(pt.y);
}

printCoord({ x: 100,  y: 100 });

这样看起来和上面的别名是一样的,TS 只关心入参的结构是否和定义的类相匹配。但是和别名也有不同之处:

在大部分情况下别名和接口都可以选择,但是别名一旦创建后就不能再添加新的属性了,

接口是可以拓展的:接口既可以新增属性名称也可以通过 extends 进行拓展。

接口 VS 别名
interface 接口 type 别名

interface Animal {
  name: string
}

interface Animal {

  legs: number
}

type Animal = {
  name: string
}

type Animal = { //报错:声明重复
  legs: number
}

interface Bear extends Animal {
  honey: boolean
}
type Bear = Animal & {
  honey: boolean
}
接口通过 extends 进行拓展 类别名通过相交进行‘拓展’

 

🔯 类型断言

有时某个值的类型信息是TS不知道的。比如你使用 document.getElementById,TS 仅仅知道返回 HTMLElement 类型,

如果在你的页面中通过ID可以获取一个 HTMLCanvasElement,在这种情况下,可以使用类型断言指定更具体的类型。

例如:

const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;

 

🔯 字面量类型

在ts中声明一个变量,ts会根据初始值自动判断变量的类型,例如:

let changingString = 'Hello World'

changingString = 'Bowen' 😊

changingString = 124  🤢

直接声明一个字面量的类型是没有多大意义的,因为这样导致变量只能有唯一的值,例如:

let x: 'text' = 'text'

x = 'text' 😊

x = 'test' 🤢

但是将字面量与联合类型相结合,便可以表达出更有用的类型,比如一个方法仅仅接收一系列预设的值:

function printText(s: string, alignment: "letf" | "right" | "center") { ... }

printText("boy", "right") 😊

printText("boy", "top")  🤢

当然了这种结合可以多种类型互相配合的:

interface Options {
  width: number;
}
function configure(x: Options | "auto"): Options | "auto" {
  return x || 'auto'
}
configure({ width: 100 }); 😊
configure("auto"); 😊
configure("automatic"); 🤢
 
👀 在使用字面量类型时,注意已经定义了字面量类型的变量或者参数,在调用时需要注意字面量类型和基础类型是不同的,下面一个例子:
声明一个方法:
 
function handleRequest(url: string, method: "GET" | "POST") {...}
const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);
报错信息:Argument of type 'string' is not assignable to parameter of type 'GET' | 'POST'
 
入参类型是string,但是接收参数的类型希望是'GET'或者'POST'
因为ts会在创建req和调用handleRequest之间预估参数类型,前者相当于创建了一个对象(两个属性的类型均为 string),
而后者的入参是一个对象(两个属性分别是 string 和 字面量类型 'GET' | 'POST'),所以这里就会报错了。
 
🔧 解决方法:
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);
as const 后缀的作用类似于const,但用于类型系统,确保所有属性都被指定为字面量类型,而不是更通用的版本,如字符串或数字。

 

posted on 2022-01-05 11:28  Deflect-o-Bot  阅读(170)  评论(0编辑  收藏  举报