TS
- TypeScript是JavaScript的超集,主要通过静态类型检查的能力在编译阶段发现JS代码问题
- TS中的module与ES Module类似,通过import和export导入导出,但TS中可以通过 declare module 来声明外部依赖
- 枚举用来定义一个常量组合,默认每一项值为数字,也可以单独设置每一项值
- Interface和type都可以用来表示对象或者函数类型,且可以相互继承
- 多个同名interface会进行属性合并,type不行
- type还可以声明其他基本类型,interface不行
- Omit用于从一个复杂类型中剔除某些属性,Pick用于从其中指定某些属性
- 泛型用于通用类型,由外部调用者自己控制调用函数(或类)中的参数类型
namespace vs module
- namespace 是为了解决命名冲突的问题,本质是一个对象,将一系列相关的全局变量组织到一个对象的属性。使用export导出变量。有ES6后,官方已经不推荐使用namespace了。
- module是ts中代码管理的方式。任何包括import或export语句的文件都是module。
装饰器
- 格式:@后面是个函数名。函数接受所修饰对象的一些相关值为参数,函数要么不返回值,要么返回一个新对象取得目标对象。
- 分为类装饰器、方法装饰器、属性装饰器。
- 多个装饰器,先执行内层装饰器。
- 在2022年分为新旧装饰器语法,但目前大量使用的是旧装饰器语法。
- 新装饰器参数是:value(所装饰的对象)、context(上下文)
- 旧装饰器参数是:类装饰器:target
- 方法属性装饰器:target、方法名/属性名
运算符
- keyOf
- in
- 方括号运算符[]:从对象取出属性的类型,
- is :说明关系 如果A is B 则返回true
- extends...?:三目运算符
Exclude<a, b>
- 排除a中的b
type vs interface
- 拓展方式: &,extends
- 合并声明:interface支持
- 表示范围:interface只能定义对象
- 默认值:type可以定义默认值
- 使用范围:type可以在函数内部使用
ts 中 any 和 unknown
- any 类型是一种“逃脱类型检查”的类型。当一个变量被声明为 any 类型时,你可以对它进行任何操作,包括调用任意属性或方法,而不会收到 TypeScript 编译器的任何错误提示。
- unknown 类型表示该变量的类型是未知的,它是一种安全的“多类型”类型。对 unknown 类型的变量进行操作时,必须进行类型检查或类型断言(如 typeof),否则 TypeScript 编译器会报错。
- unknown 可以看作是更安全的 any。一般来说,凡是需要设为 any 类型的地方,通常都应该优先考虑设为 unknown 类型
高阶用法汇总
1. 高级类型
- 联合类型:使用 | 来表示一个变量可以是多种类型中的一种ts
let value: string | number; value = "Hello"; value = 42;
- 交叉类型:使用 & 来表示一个变量同时具有多种类型的·ts
type A = { a1: string; } type B = { b1: number; } let value: A & B = { a1: "Hello", b1: 42 };
2. 范型
- 泛型是指在定义函数或类时不预先指定具体的类型,而是在使用时再指定类型。这样可以使代码更加灵活和可重用。
ts
// 泛型函数
function identity<T>(arg: T): T {
return arg;
}
// 泛型类
class Box<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
3. 映射类型
- 映射类型是指通过对已有类型进行转换来创建新类型。常用的映射类型有 Partial、Required、Readonly、Record 等。
- Partial<T>:使所有属性可选。
- Readonly<T>:使所有属性只读。
- Pick<T, K>:选择部分属性。
- Omit<T, K>:排除部分属性。
- Record<K, T>:创建拥有指定属性的类型
ts
// Partial:将所有属性变为可选
type Partial<T> = {
[P in keyof T]?: T[P];
};
// 将 T 中的所有属性变为只读属性
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
4. 条件类型
- 条件类型能够依据条件来选择类型,语法类似于三元表达式。
ts
type IsString<T> = T extends string ? true : false;
type A = IsString<string>; // true
type B = IsString<number>; // false
5. 装饰器
- 装饰器是一个特殊的类型声明,可以用来修改类、方法、属性等的行为。装饰器可以用于依赖注入、日志记录等场景。
ts
// 类装饰器示例
function logClass(target: Function) {
console.log(`Class created: ${target.name}`);
}
@logClass
class MyClass {}
6. 命名空间
- 命名空间是 TypeScript 中的一种组织代码的方式,可以将相关的代码组织在一起,避免全局命名冲突。命名空间可以包含变量、函数、类等。
ts
namespace Validation {
export interface Validator {
isValid(s: string): boolean;
}
export class EmailValidator implements Validator {
isValid(email: string) {
return email.includes('@');
}
}
}
// 使用
const validator: Validation.Validator = new Validation.EmailValidator();
7. 索引签名
- 索引签名允许对象使用任意数量的属性,并且这些属性的类型可以是相同的。
ts
interface StringArray {
[index: number]: string; // 索引签名
}
const myArray: StringArray = ["Hello", "World"];
demo
- 若要实现一个函数,使其在传入 User 对象的键名(如 'name')时返回对应值的类型,可通过 泛型 + keyof + 索引访问类型 组合实现。以下是具体实现步骤和代码:
ts
// T:任意对象类型,K:T 的键名
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
return obj[key];
}
// 使用示例
const person = { name: "Bob", age: 25, isAdmin: true };
// 类型推导:result 为 string
const result = getProperty(person, "name");