Typescript总结篇——配置TS、基础知识(类型、接口、类型别名、泛型、extendsinfer关键字)
配置Typescript
安装包工具对比
tsconfig.json配置
主要包括(target(编译输出的JS版本)、outDir输出路径、rootDir(根目录,通常为./src)、lib(编译过程依赖库,如dom、es6)、include&exclude需/无需编译的文件夹、paths(类似alias设置))等
基础知识
1. 类型系统
-
原始类型
:包括 number、string、boolean、null、undefined、symbol、bigint 等。 -
数组与元组
:数组使用 number[] 或 Array 表示;元组用于表示固定长度和类型的数组,如 [string, number]。
-
枚举
(enum):定义一组命名的常量,提升代码可读性。
-
void空值
-
any 与 unknown
:any 表示任意类型
,关闭类型检查;unknown 也表示任意类型,但更安全,使用前需进行类型检查
。 -
类型断言
:通过 as 关键字或尖括号语法 ,手动指定变量的类型。
2. 接口与类型别名
接口(interface)
定义对象的结构,如属性和方法,用于定于定义对象结构,可指定对象(对象->类->抽象类(可包括具体方法
)->接口)属性、方法及其类型,可以通过继承extends实现implement
进行复用
- 可选属性
- 只读属性
- 抽象方法
(name:string):string
类型别名(type)
为类型起一个新名字,可用于联合类型、交叉类型等。
- 联合类型 | type status=“pending”|“fulfilled”|“rejected”
- 交叉类型 &
3.泛型(Generics)
泛型允许在定义函数、接口或类时不预先指定具体的类型
,而在使用时再指定类型,
提高代码的复用性和类型安全性
。
- 泛型函数
function identity<T>(arg:T):T{return arg;
}
- 泛型接口
interface IdentityFn<T>{(arg:T)=>T;
}
const identity:IdentityFn<number>=(arg)=>arg;
- 泛型类
class BoxClass<T>{value:T;constructor(val:T){this.value=val;}
}
const box=new Box(10);
- 泛型约束
function getLength<T extends {length:number}>(arg:T):number{return arg.length;
}
4.类型推导(Type Inference)
5. extends关键字详解
用于继承类
用于泛型约束
用于约束泛型的类型,确保泛型类型满足特定条件
function getLength<T extends {length:number}>(arg:T):number{return arg.length;
}
用于条件类型的类型推断
- 条件类型
type IsString<T>=T extends string?"Yes":"No";
type Test1=IsString<string> //"Yes"
extends+infer
,条件类型中类型中提取和推断
类型
type ExtractReturnType<T> =T extends (...args:any[])=>infer R?R:never;
type Func=(a:number,b:number)=>string;
type ReturnTypeOfFunc=ExtractReturnType<Func>;//推导为string
- 条件类型和extends
type isFun<T>=T extends Function?"a function":"not a function";
type Results=isFun<()=>void>
6. infer关键字
infer主要用于条件类型中
,可以根据类型推断出一个子类型
,并将其赋给一个新的类型变量
。infer通常与条件类型(extends)结合使用,允许你从某些类型中提取部分信息。
函数类型解构(参数、返回值);
获取函数返回类型
type ReturnTypeOf<T>=T extends(...args:any[])=>infer R?R:never;
function greet(name:string):string{return `Hello ${name}`;
}
type GreetReturnType=ReturnTypeOf<typeof greet>//推到出string
容器类型提取(数组、Promise)
//元素类型提取
type ElementType<T> = T extends (infer U)[] ? U : never;
type NumElement = ElementType<number[]>; // number //元组操作
type FirstElement<T> = T extends [infer F, ...any[]] ? F : never;
type First = FirstElement<[number, string]>; // number //Promise结果类型
type UnpackPromise<T> = T extends Promise<infer R> ? R : never;
type PromiseResult = UnpackPromise<Promise<string>>; // string //对象属性
type PropType<T, K extends keyof T> = T extends { [P in K]: infer V } ? V : never;
type Age = PropType<{ age: number }, "age">; // number [5,7]
字符串模板处理
type Prefix<T> = T extends `${infer P}_${string}` ? P : never;
type Pre = Prefix<"hello_world">; // "hello"
递归与联合类型操作
//递归
type Flatten<T> = T extends Array<infer U> ? Flatten<U> : T;
type FlatArr = Flatten<number[][][]>; // number //联合类型
type ExtractStrings<T> = T extends infer U ? (U extends string ? U : never) : never;
type StrOnly = ExtractStrings<string | number>; // string
7 函数类型
- 参数类型与返回值类型:明确函数的输入输出类型。
- 可选参数与默认参数:使用
?
表示可选参数,使用=
指定默认值。 - 剩余参数:使用
...args: Type[]
表示不定数量的参数。(维基百科, notes.fe-mm.com)
8. 模块与命名空间
- 模块(module):使用
import
和export
实现模块化,支持 ES6 的模块系统。 - 命名空间(namespace):用于组织代码,避免命名冲突,适用于较大的项目。
🚀 TypeScript 高级应用
1. 泛型(Generics)
泛型允许在定义函数、接口或类时不预先指定具体的类型,而在使用时再指定类型,提高代码的复用性和类型安全性。
function identity<T>(arg: T): T {return arg;
}
2. 条件类型(Conditional Types)
根据类型的条件进行类型选择,常用于类型映射和类型推导。
type IsString<T> = T extends string ? true : false;
3. 映射类型(Mapped Types)
基于已知的类型创建新的类型
,常用于对类型进行批量修改。
type Readonly<T> = {readonly [P in keyof T]: T[P];
};
使用
keyof 操作符
获取类型 T 的所有属性名
,形成一个联合类型
。然后,使用映射类型语法[P in keyof T] 遍历这些属性名
.
4. 工具类型(Utility Types)
TypeScript 提供了一些内置的工具类型,如:
- Partial:将类型 T 的所有属性变为可选。
- Required:将类型 T 的所有属性变为必选。
- Readonly:将类型 T 的所有属性变为只读。
- Pick<T, K>:从类型 T 中选择一组属性 K。
interface User {id: number;name: string;email: string;age: number;
}type UserContactInfo = Pick<User, 'name' | 'email'>;
// 等价于:
// {
// name: string;
// email: string;
// }
- Omit<T, K>:从类型 T 中排除一组属性 K。(CSDN博客, 知乎专栏)
interface User {id: number;name: string;email: string;age: number;
}type UserWithoutEmail = Omit<User, 'email'>;
// 等价于:
// {
// id: number;
// name: string;
// age: number;
// }
5. 类型守卫(Type Guards)
在运行时检查变量的类型,以实现类型缩小。常见的类型守卫有:(掘金)
- typeof:用于检查原始类型。
- instanceof:用于检查对象的实例。
- 自定义类型守卫:通过函数返回值为类型谓词的方式定义。
function isString(value: any): value is string {return typeof value === 'string';
}
6. 模板字面量类型(Template Literal Types)
通过模板字符串的方式构造新的字符串字面量类型。(掘金)
type EventName = `on${Capitalize<string>}`;