TypeScript

A Typed Superset of JavaScript.

  • TypeScript is a language that is a superset of JavaScript: JS syntax is therefore legal TS.
  • TypeScript is a typed superset, meaning that it adds rules about how different kinds of values can be used.
  • TypeScript never changes the runtime behavior of JavaScript code, even if TypeScript thinks that the code has type errors.

对象类型声明

JavaScript的变量具有类型,但使用前无需声明。TypeScript增加了类型声明,从而支持静态类型检查。

基础类型

stringnumber, and boolean

let myName: string = "Alice";

bigint [ES2020]

null and undefined with strictNullChecks on:必须处理变量为nullundefined的情形。

Non-null Assertion Operator
function liveDangerously(x?: number | null) {
    console.log(x!.toFixed());  // ! add assertion for null/undefined
}

数组

string[], number[], boolean[] or Array<number>

any

表示任意类型,避免类型检查错误。任何无法自动推测的对象会被视为any类型导致跳过类型检查,在项目配置中设置noImplicitAny将无法推测的类型视为错误。

对象类型

let pt: {x: number; y: number} = {x:3, y:7};
let name: {first: string; last?: string};
name.last !== undefined    // check optional property existence

函数

// Parameter type annotation
function greet(name: string): number {
    console.log("Hello, " + name.toUpperCase() + "!!");
    return 0;
}

匿名函数参数类型可根据其调用==上下文推断==,因此无需声明其参数类型。

函数类型变量声明

函数也是一种变量类型,因此可以用于类型声明。

function func(fn: (a: string)=>void)
type GreetFunction = (a: string) => void; // 为函数类型定义别名*

*:函数类型声明中必须同时给出参数名和参数类型名;如果省略参数名,则会将参数类型名视为参数名,而将对应的参数类型视为Any

带属性的函数类型
type DescribableFunction = {
  description: string;        // 属性
  (someArg: number): boolean; // 函数原型
};
构造函数类型

使用此类声明的函数函数类型标识new方法调用以创建某类对象。构造函数类型可与普通调用方法并列声明(根据参数类型决定调用对象)。

type SomeConstructor = {
  new (s: string): SomeObject;
};
interface CallOrConstruct {
  new (s: string): Date;
  (n?: number): number;
}

函数泛型参数声明

function firstElement<Type>(arr: Type[]): Type | undefined {}
function map<Input, Output>(arr: Input[], func: (arg: Input) => Output): Output[] {}
泛型类型限制

限制类型应具有的接口(包含的属性)。

function longest<Type extends { length: number }>(a: Type, b: Type) {}

联合类型

let id: number | string;
function print(obj: number|string){/*...*/}

其他判断条件:Array.isArray(x)

字面值枚举

let alignment: "left" | "right" | "center" = "center";

字面值可以和其他类型组合成联合类型。

类型限制(Narrowing)

联合类型默认仅能调用类型的公共方法,可通过类型判断typeof在分支中调用类型特有的方法。

if (typeof id === "string") { // [type guard]
    // In this branch, id is of type 'string'
    console.log(id.toUpperCase());
} else {
    // Here, id is of type 'number' 
    console.log(id);
}

typeof支持返回以下类型:"string""number""bigint""boolean""symbol""undefined""object""function"

TypeScript: Documentation - Narrowing (typescriptlang.org)

类型别名

type Point = {
    x: number;
    y: number;
};
let pt: Point = {x:3, y:7};
type ID = number | string;
let id: ID = 1001;

接口

接口类似于类型别名,但支持继承语法(类型别名也可以不同语法实现),并可以动态添加属性(类型别名不支持)。

interface Animal {
  name: string
}  
interface Animal {
  weight: number   // Animal: {name, weight}
}  
interface Bear extends Animal {
  honey: boolean
}

类型断言

根据代码运行的实际情况,将对象显式转换为已知的类型。

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

仅允许具有继承关系的类型进行相互转换。对于未知关系的类型,确实需要转换的情况,可先转换为anyunknown,再转换为目标类型。

const a = (expr as any) as T;