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增加了类型声明,从而支持静态类型检查。
基础类型
string
, number
, and boolean
let myName: string = "Alice";
bigint
[ES2020]
null
and undefined
with strictNullChecks
on:必须处理变量为null
或undefined
的情形。
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");
仅允许具有继承关系的类型进行相互转换。对于未知关系的类型,确实需要转换的情况,可先转换为any
或unknown
,再转换为目标类型。
const a = (expr as any) as T;