TypeScript 语法
PR:
- customElements.whenDefined
- elementinternal
- AOM
// 不要为了类型而类型,一定要保持代码可读性
VS Code 调试(类似 Babel):https://medium.com/@dupski/debug-typescript-in-vs-code-without-compiling-using-ts-node-9d1f4f9a94
Template Literal Types: type Greeting = `hello ${World}`;
Key Remapping in Mapped Types: type Mapped = {[K in keyof T as `get${Capitalize}` ]: T[K]}
Recursive Conditional Types: type ElementType = T extends ReadonlyArray ? ElementType : T;
—noUncheckedIndexedAccess
function getNamesExactly(arg: T)
Object 类型是 Object 示例, object 类型是非原始值类型
会类型自动推导
函数重载 Overload // 在实现函数/方法上面手写签名
声明合并
satisfies 是做类型约束但改变原类型 // v4.9
声明
扩展全局对象:declare global { interface Window { MyNamespace: any }}; export {} // 表示 module
声明模块 declare module '*.vue' {export default Vue}
声明全局变量:declare let $0: any;
接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。只会去关注值的外形。并不能像在其它语言里一样,使用这个接口进行类型检查时时要实现这个接口
接口是一个实体,可以导入导出
interface LabelledValue {
label: string;
size?: number; // 可选属性
readonly width: number; // 只读属性
setTime(d: Date); // 方法
[index: number]: string; // 可数字索引的类型,数字索引的返回值必须是字符串索引返回值类型的子类型
[propName: string]: any; // 可能带有其他属性
}
-readonly PorpName: 移除属性上的 readonly 修饰符 // Required -?
type NullableKeys = { [K in keyof T]-?: undefined extends T[K] ? K : never }[keyof T]
interface SearchFunc {
(source: string, subString: string): boolean;
// 为函数添加属性
// (arg: T): T;
}
继承 interface Square extends Shape, PenStroke
接口同样会继承到类的 private 和 protected 成员
范型接口: interface SearchFunc {}
可以把类当接口使用
never: 不会返回值,例子:type Exclude = T extends U ? never : T;
元组:固定元素以及固定元素类型的数组
构造函数:
interface ObjectConstructor {
/** Invocation via `new` */
new(value?: any): Object;
/** Invocation via function calls */
(value?: any): any;
}
范型
function identity(arg: T): T { return arg }
function identity(arg: T[]): T[] { return arg } // 成员是范型 T 的数组
泛型类指的是实例部分的类型,所以类的静态属性不能使用这个泛型类型
实现
强制一个类去符合某种契约:class Clock implements ClockInterface
枚举
使用枚举我们可以定义一些带名字的常量
enum Direction {Up = 1,Down} // 第一个是数字,后面的会自动加1
类型别名 type Type = 1 | 2 | 3 类似
类
私有字段:private // 只允许在该类中访问,标准里面是 "#",构造函数使用时将不允许子类
protected // 只允许类中以及子类中访问
abstract:抽象类做为其它派生类的基类使用(不能实例化),抽象类中的抽象方法不包含具体实现并且必须在派生类中实现
当一个类实现了一个接口时,只对其实例部分进行类型检查
!: 未初始化的字段
标记构造函数 c: { new(): T }
// 类似对象字面量标记函数 let myIdentity: { (arg: any): number } = arg => 1 // 此方法可以进行函数 overload
命名空间
以前称为"内部模块",里面可以 export,外面可以 import
不同的文件,它们仍可以使用同一个命名空间,使用应用标签链接 ///
// test 文件可以用 js 写,然后加 reference 获得类型提示
高级类型
交叉类型:A & B & C 同时拥有他们的成员
联合类型:string | number,不是原始值时只能访问共有的成员
类型保护(type predicates):function isFish(pet: Fish | Bird): pet is Fish {} 在 if else 中有用,typeof,instanceof 自动类型保护。 null 与 undefined 是所有其它类型的一个有效值, —strictNullChecks 标记可以解决,也可以写 js 一样使用类型保护去除 null 和 undefined
类型别名 type Name = string; 和接口类似 // 区别 interface
字面量类型
多态的 this 类型表示的是某个包含类或接口的 子类型
索引类型,能够检查使用了动态属性名
keyof T
T[K], 索引访问操作符
function pluck(o: T, names: K[]): T[K][]
映射类型,拥有相同成员的另一个版本
Partial 类型: type Partial = {[P in keyof T]?: T[P]} // 类似的还有 Mapped types
从值中指定 key: keyof typeof foo
infer 推导
TypeScript 具有 ReadonlyArray 类型,它与 Array 相似,只是把所有可变方法去掉了(T 范型)
let strs: string[]; // 表示数组
类型断言(ts 不知道类型,写代码的人知道类型)
联合类型中区分类型 (pet).swim
const a = {}
const b: boolean = 5 === 2;
绕开类型检查 { width: 100, opacity: 0.5 } as SquareConfig
去除 null 和 undefined:name!.charAt(0) // 并非可选链,这个是一种标记
Mixins:TypeScript 只做了类型上的检测,实际上需要 minix 函数支持