1.JSDoc注释
/**
* 这是JSDoc注释
* 这也是JSDoc注释
* 这还是JSDoc注释
*/
2.非运算符
非运算符 | 描述 |
标识符? | 用于函数的形参名、对象类型的属性名后面,表示是可选的(可传递实参,也可不传递实参,当不传递实参的时候,相当于传递了 undefined 值)。 |
3.类型
3.1常用类型
类型 | 描述 |
bigint | 大整数类型 |
number | 数值类型 |
boolean | 布尔类型 |
string | 字符串类型 |
symbol | 符号类型 |
undefined | Undefined类型 |
null | Null类型 |
类名 | 类类型 |
{ 属性名1: 类型1; 属性名2: 类型2 } | 对象类型是匿名的,可以使用类型别名和接口这两种方式命名对象类型。 对象类型的属性之间使用 , 或者 ; 分隔,最后一个属性后面的 , 或者 ; 是可以省略的。 |
接口名 | 接口类型 |
(形参名: 类型) => 返回类型 | 函数类型表达式,类似于 C# 语言的委托(Delegate)类型。 |
类型[] 或 Array<类型> | 数组类型 |
readonly 类型[] 或 ReadonlyArray<类型> | 只读数组类型 |
[类型1, 类型2, 类型N] | 元组类型是一种特殊的数组类型,可声明指定索引对应的元素类型。 |
readonly [类型1, 类型2, 类型N] | 只读元组类型 |
枚举名 | 枚举类型 |
类型1 | 类型2 | 类型N | 联合(Union)类型表示实参只需要满足联合类型中的多个类型的一种即可。 |
类型1 & 类型2 & 类型N | 交叉(Intersection)类型表示必须同时满足交叉类型中的所有类型。 |
字面量 | 字面量类型 |
`模板字面量` | 模板字面量类型 |
any | any 类型表示不限定哪一种具体类型。 |
unknown | unknown 类型表示除了 any 类型以外的类型。 |
typeof 表达式 | typeof 类型 |
type 别名 = keyof 对象类型; | keyof 类型,表示接受一个对象类型,将对象类型的属性名组成联合类型。 |
type 别名 = 类型["index"]; | Indexed Access 类型 |
type 别名 = 类型A extends 类型B ? 类型C : 类型D; | 条件类型 |
type 别名<类型形参> = { | Mapped 类型 |
void | void返回类型,表示函数没有返回值。 |
never | never返回类型,表示函数抛出异常或终止程序的执行。 |
形参名 is 类型 | 类型谓词(type predicate),用于函数的返回类型,形参必须是当前函数签名中的形参。 |
3.2签名
签名 | 描述 |
[变量名: 类型]: 类型 | 索引签名 |
new(): 返回类型 | 抽象构造函数签名 |
new(形参名: 类型): 返回类型 | 构造函数签名 |
3.3类型别名
类型别名可用于任何类型。
type 别名 = 类型;
3.4类型断言
有时候我们比 TypeScript 更知道值的类型信息。在这种情况下,我们可以使用 as
表示类型断言来指定更具体的类型。
类型断言 | 描述 |
as 类型 | 单个断言 |
as any as 类型 | 多个断言 |
as const | 断言对象的所有属性的类型为字面量类型(属性的值)。 |
标识符! | 场景一:断言传递给函数的实参值不是 null 或 undefined 。场景二:断言通过构造函数以外的方式初始化一个字段(例如,可能通过外部库填充类的部分字段)。 |
//as
const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement;
//as any as 类型
const a = expr as any as T;
//as const
declare function handleRequest(url: string, method: "GET" | "POST"): void;
const req = { url: "https://example.com", method: "GET" } as const;
handleRequest(req.url, req.method);
//标识符!
//场景一
function liveDangerously(x?: number | null) {
//无报错
console.log(x!.toFixed());
}
//场景二
class OKGreeter {
//无报错
name!: string;
}
TypeScript 只允许类型断言转换为更具体或更不具体的类型版本。
//报错:Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
const x = "hello" as number;
4.变量
//变量声明
//声明后再初始化
let 变量名: 类型;
变量名 = 值;
//声明时同时初始化
let 变量名: 类型 = 值;
5.常量
//声明常量时必须同时初始化
const 常量名: 类型 = 值;
6.函数
注意:匿名函数表达式和箭头函数表达式使用类型推导。
//函数声明
function 函数名(值形参名: 类型, 可选形参名?: 类型, ...剩余形参名: 类型[]): 返回类型 {
//函数体
}
7.类
7.1抽象类
抽象类可以包含抽象实例方法、具体实例方法。
派生类必须实现抽象超类中的所有抽象方法。
抽象类不可以被实例化。
abstract class Base {
abstract getName(): string;
printName() {
console.log("Hello, " + this.getName());
}
}
7.2形参属性(Parameter Property)
构造函数的形参必须添加 public
、protected
、private
、readonly
这四个修饰符中的一个。
class Params {
constructor(public readonly x: number, protected y: number, private z: number) {
//无代码
}
}
//同等代码
class Params {
public readonly x: number;
protected y: number;
private z: number;
constructor(x: number, y: number, z: number) {
this.x = x;
this.y = y;
this.z = z;
}
}
7.3函数重载(Overload)
如果在同一个类中多个函数的函数名相同,但形参类型、形参个数不相同,则此时多个函数之间便形成了重载。
注意:返回类型不是函数签名的一部分。
首先编写多个重载签名(Overload Signature),然后编写与所有重载签名兼容的实现签名(Implementation Signature),最后 TypeScript 会根据重载规则解析到对应的重载签名,以运行实现签名。
注意:实现签名是不可以直接被调用的。
//重载签名
function makeDate(timestamp: number): Date;
function makeDate(m: number, d: number, y: number): Date;
//实现签名
function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
if (d !== undefined && y !== undefined) {
return new Date(y, mOrTimestamp, d);
} else {
return new Date(mOrTimestamp);
}
}
//调用重载签名
const d1 = makeDate(12345678);
const d2 = makeDate(5, 5, 5);
7.4readonly关键字
readonly
关键字表示字段是只读的,只可以声明时初始化或者构造函数初始化。
注意:当字段的值是对象时,可以改变对象的内部状态。
class Greeter {
readonly name: string = "world";
constructor(otherName?: string) {
if (otherName !== undefined) {
this.name = otherName;
}
}
//报错:Cannot assign to 'name' because it is a read-only property.
err() {
this.name = "not ok";
}
}
const g = new Greeter();
//报错:Cannot assign to 'name' because it is a read-only property.
g.name = "also not ok";
8.接口
8.1接口声明
接口是给对象类型命名的一种方式。
interface 接口名 {
//接口体
}
8.2接口继承
一个派生接口可以继承自多个超接口。
派生接口会继承超接口内的成员。
interface 派生接口名 extends 超接口名1, 超接口名2 {
//派生接口体
}
8.3实现接口
一个类可以实现多个接口。
class 类名 implements 接口名1, 接口名2 {
//类体
}
8.4接口声明合并
如果存在多个相同名称的接口声明时,不会出现命名冲突,接口声明会自动合并。
interface Window {
title: string;
}
interface Window {
ts: TypeScriptAPI;
}
const src = 'const a = "Hello World"';
window.ts.transpileModule(src, {});
8.5readonly关键字
readonly
关键字表示属性是只读的。
注意:当属性的值是对象时,可以改变对象的内部状态。
interface SomeType {
readonly prop: string;
}
function doSomething(obj: SomeType) {
//可以读取obj.prop的值
console.log(`prop has the value '${obj.prop}'.`);
//不可以赋值给obj.prop
//报错:Cannot assign to 'prop' because it is a read-only property.
obj.prop = "hello";
}
9.枚举
枚举内的成员为常量。根据常量的值是数值还是字符串,分为数值枚举和字符串枚举。虽然同一个枚举内的常量的值可以混合数值和字符串,但一般不建议这么做。
9.1枚举声明
数值枚举内的常量非必须有值,值会按 1
自动递增。
字符串枚举内的常量必须有值,且值必须为字符串字面量或另一个字符串枚举的成员。
//数值枚举
//Up=0,Down=1,Left=2,Right=3。
enum Direction {
Up,
Down,
Left,
Right,
}
//Up=1,Down=2,Left=3,Right=4。
enum Direction {
Up = 1,
Down,
Left,
Right,
}
//字符串枚举
enum Direction {
Up = "UP",
Down = "DOWN",
Left = "LEFT",
Right = "RIGHT",
}
9.2创建枚举类的实例
枚举类内的常量就是枚举类的实例。
9.3访问枚举类的实例
枚举名.常量名
10.泛型(Generic)
10.1类型形参
类型形参使用尖括号 <>
括起来。
类型形参不可以用于类的静态成员。
//单个类型形参
<类型形参>
//多个类型形参
<类型形参1, 类型形参2>
<类型形参 extends 限定类型>
<类型形参 extends 限定类型 = 默认类型>
10.2类型实参
类型实参使用尖括号 <>
括起来。
<类型实参>
10.3泛型类
泛型类声明和使用泛型类时,<类型形参>
和 <类型实参>
都放置在类名的后面。
//泛型类声明
class 类名<类型形参> {
//类体
}
//使用泛型类
const 常量名 = new 类名<类型实参>();
10.4泛型接口
泛型接口声明和使用泛型接口时,<类型形参>
和 <类型实参>
都放置在接口名的后面。
//泛型接口声明
interface 接口名<类型形参> {
//接口体
}
//使用泛型接口
const 常量名: 接口名<类型实参> = ...;
10.5泛型函数
泛型函数声明和调用泛型函数时,<类型形参>
和 <类型实参>
都放置在函数名的后面。
//泛型函数声明
function 函数名<类型形参>() {
//函数体
}
//调用泛型函数
函数名<类型实参>();
11.可见性(Visibility)
成员的可见性默认是 public
,无需在成员标识符前显式添加。
注意:JavaScript 语言无 protected
修饰符。
注意:TypeScript 的 private
是 soft private,而 JavaScript 的 #private
是 hard private。
public
protected
private
原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/javascript/javascriptlang/33428.html