Typescript 基本类型
核心是在我们的 javascript 的基础数据类型的基础上实现新增了对应的元组和枚举两大数据类型吧
interface 定义接口和 type 的类型别名的定义
总结吧
type 是可以定义所有的类型的,interface 核心是用来定义我们的对象的数据类型的讷,type核心功能是进行定义类型别名的,interface 核心是定义的树接口声明的
interface 在多次声明的时候是会被类型合并的,但是 type 不会讷
interface 通过 extends 进行类型的扩展,type通过交叉数据类型进行对应的扩展吧
&interface:对象类型专用,支持合并和extends扩展,适合定义可扩展的结构。type:通用类型定义,支持任意类型,用交叉类型扩展,适合复杂类型组合。
javascript 的基础数据类型有那些讷
number
boolean
null
undefined
symbol
string
bigint
javascript 的引用数据类型
map
set
weakset
weakmap
object
array
Function
let num: number = 10; // 显示的指定我们的类型声明吧
let str: string = "hello world" // 字符串类型
let strs: string[] = []
// 元组数据类型的定义
let useState: [string, Function] = [
"hello world",
() => void
]Typescript 高级类型
交叉类型Intersection Type
核心就是使用的是我们的
&进行对应的开发实现吧交叉类型实现的就是我们的将数据类型进行合并的操作吧
interface A {
a: string
}
interface B {
b: string
}
type C = A & B;
// 此时我们的 C 就有了对应的 A + B 的类型定义了吧联合类型Unions Type
核心是使用我们的关键字
|表示的意思是我们的类型可以是 A 或者 B
interface A {
a: string
}
interface B {
b: string
}
type C = A | B;类型保护和区分类型
function padLeft(value: string, padding: string | number) {
if (typeof padding === 'number') {
return Array(padding + 1).join(" ") + value
}
if (typeof padding === 'string') {
return padding + value
}
throw new Error("")
}
interface Fish {
swim(): void;
name: string;
}
interface Bird {
fly(): void;
name: string;
}
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
function move(pet: Fish | Bird) {
if ("swim" in pet) {
return pet.swim();
}
return pet.fly();
}索引类型
也就是实现的是使用我们的索引类型吧
function pluck<T, K extends keyof T>(obj: T, keys: K[]): T[K][] {
return keys.map(key => obj[key])
}
interface Car {
manufacturer: string;
model: string;
year: number
}
let taxi: Car = {
manufacturer: '',
model: '',
year: 0
}
// 获取 manufacturer 和 model 的值的数组
let makeAndModel: string[] = pluck(taxi, ['manufacturer', 'model']);泛型工具
// 让 T 的所有属性变成可选的
type Partial<T> = {
[P in keyof T]?: T[P];
};
// 让 T 的所有属性变成只读的
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
// 从 T 中选取一组属性 K
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
// 构造一个类型,其属性名为 K,属性值为 T
type Record<K extends keyof any, T> = {
[P in K]: T;
};
// 从 T 中排除掉 U
type Exclude<T, U> = T extends U ? never : T;
// 从 T 中提取 U
type Extract<T, U> = T extends U ? T : never;
// 从 T 中排除 null 和 undefined
type NonNullable<T> = T extends null | undefined ? never : T;
// 获取函数返回类型
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
// 获取函数参数类型
type Parameters<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never;
// 获取构造函数参数类型
type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never;
// 获取实例类型
type InstanceType<T extends new (...args: any) => any> = T extends new (...args: any) => infer R ? R : any;自定义类型工具
// 将 T 的所有属性变为必需的
type Required<T> = {
[P in keyof T]-?: T[P];
};
// 将 T 的所有属性变为可变的(移除 readonly)
type Mutable<T> = {
-readonly [P in keyof T]: T[P];
};
// 获取函数的第一个参数类型
type FirstParameter<T extends (arg: any) => any> = T extends (arg: infer P) => any ? P : never;
// 获取数组类型
type ArrayType<T> = T extends (infer U)[] ? U : never;
// 深度只读
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};
// 深度可选
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
// 将联合类型转换为交叉类型
type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
// 将联合类型转换为元组类型(比较复杂,通常需要递归条件类型)
// 注意:联合类型的顺序是不确定的,所以转换后的元组顺序也是不确定的
type UnionToTuple<T> =
UnionToIntersection<T extends any ? () => T : never> extends () => infer R
? [...UnionToTuple<Exclude<T, R>>, R]
: [];
// 获取对象类型的值类型
type ValueOf<T> = T[keyof T];
// 获取 Promise 的返回值类型
type Awaited<T> = T extends Promise<infer U> ? U : T;
// 将字符串字面量类型按分隔符拆分为元组
type Split<S extends string, D extends string> =
string extends S ? string[] :
S extends '' ? [] :
S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] : [S];
// 获取数组元素类型
type Flatten<T> = T extends (infer U)[] ? U : T;
// 获取函数返回类型
type MyReturnType<T> = T extends (...args: any) => infer R ? R : any;
// 获取函数参数类型
type MyParameters<T> = T extends (...args: infer P) => any ? P : never;
// 深度只读
type DeepReadonly<T> = {
readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};
// 将嵌套数组展平
type FlattenDepth<T extends any[]> =
T extends [infer First, ...infer Rest]
? First extends any[]
? [...First, ...FlattenDepth<Rest>]
: [First, ...FlattenDepth<Rest>]
: [];
// 字符串替换
type Replace<S extends string, From extends string, To extends string> =
From extends ''
? S
: S extends `${infer Prefix}${From}${infer Suffix}`
? `${Prefix}${To}${Suffix}`
: S;
// 字符串去空格
type TrimLeft<S extends string> =
S extends ` ${infer R}` ? TrimLeft<R> : S;
type TrimRight<S extends string> =
S extends `${infer R} ` ? TrimRight<R> : S;
type Trim<S extends string> = TrimLeft<TrimRight<S>>;
// 字符串分割
type Split<S extends string, D extends string> =
string extends S ? string[] :
S extends '' ? [] :
S extends `${infer T}${D}${infer U}` ? [T, ...Split<U, D>] : [S];
// 定义路由参数类型
type RouteParams<T extends string> =
T extends `${string}:${infer Param}/${infer Rest}`
? { [K in Param | keyof RouteParams<Rest>]: string }
: T extends `${string}:${infer Param}`
? { [K in Param]: string }
: {};
// 使用
type Test1 = RouteParams<'/user/:id'>; // { id: string }
type Test2 = RouteParams<'/user/:id/:name'>; // { id: string, name: string }
type Test3 = RouteParams<'/user/:id/:name/edit'>; // { id: string, name: string }
// 路由配置
interface RouteConfig<T extends string> {
path: T;
component: React.ComponentType;
params: RouteParams<T>;
}
function createRoute<T extends string>(config: RouteConfig<T>) {
return config;
}
const route = createRoute({
path: '/user/:id/:name',
component: UserComponent,
params: { id: '123', name: 'John' } // 类型检查
});
// 深度可选
type DeepPartial<T> = {
[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];
};
// 深度必需
type DeepRequired<T> = {
[P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P];
};
// 可变类型
type Mutable<T> = {
-readonly [P in keyof T]: T[P];
};
// 获取嵌套属性类型
type Get<T, K extends string> =
K extends keyof T ? T[K] :
K extends `${infer First}.${infer Rest}`
? First extends keyof T
? Get<T[First], Rest>
: never
: never;
// 设置嵌套属性类型
type Set<T, K extends string, V> =
K extends keyof T ? Omit<T, K> & Record<K, V> :
K extends `${infer First}.${infer Rest}`
? First extends keyof T
? Omit<T, First> & Record<First, Set<T[First], Rest, V>>
: T
: T;
// 函数组合类型
type Compose<F extends Array<Function>> =
F extends [infer First, ...infer Rest]
? First extends (...args: any[]) => any
? Rest extends Array<Function>
? (...args: Parameters<First>) => ReturnType<Compose<Rest>>
: never
: never
: () => void;
// 柯里化类型
type Curry<F extends (...args: any[]) => any> =
F extends (...args: infer Args) => infer R
? Args extends [infer First, ...infer Rest]
? (arg: First) => Curry<(...args: Rest) => R>
: R
: never;
// 异步函数处理
type AsyncFunction<T extends any[], R> = (...args: T) => Promise<R>;
type Awaited<T> = T extends Promise<infer U> ? U : T;
type AsyncReturnType<T extends (...args: any) => any> =
Awaited<ReturnType<T>>;
// 类型安全的 API 定义
type ApiDefinition = {
[Endpoint: string]: {
[Method in 'GET' | 'POST' | 'PUT' | 'DELETE']?: {
params?: Record<string, string>;
query?: Record<string, string | number | boolean>;
body?: unknown;
response: unknown;
};
};
};
// 路径参数提取
type ExtractPathParams<Path extends string> =
Path extends `${string}{${infer Param}}${infer Rest}`
? Param | ExtractPathParams<Rest>
: never;
// API 客户端类型
type ApiClient<API extends ApiDefinition> = {
[Endpoint in keyof API]: {
[Method in keyof API[Endpoint]]:
API[Endpoint][Method] extends { params: infer P, response: infer R }
? (params: P) => Promise<R>
: API[Endpoint][Method] extends { response: infer R }
? () => Promise<R>
: never;
};
};
// 示例 API 定义
type MyApi = {
'/users/{userId}': {
GET: { params: { userId: string }; response: User };
PUT: { params: { userId: string }; body: Partial<User>; response: User };
};
'/posts': {
GET: { query: { page: number; limit: number }; response: Post[] };
POST: { body: CreatePost; response: Post };
};
};
type Client = ApiClient<MyApi>;
// 自动获得类型安全的客户端方法
// 基础验证类型
type ValidationResult<T> =
| { valid: true; value: T }
| { valid: false; error: string };
// 验证器组合
type Validator<T> = (value: unknown) => ValidationResult<T>;
type AndValidator<A, B> = <T extends A & B>(
value: unknown
) => ValidationResult<T>;
type OrValidator<A, B> = (
value: unknown
) => ValidationResult<A | B>;
// 模式验证
type Schema = {
[key: string]: Validator<any>;
};
type InferSchema<T extends Schema> = {
[K in keyof T]: T[K] extends Validator<infer U> ? U : never;
};
function createValidator<T extends Schema>(schema: T): Validator<InferSchema<T>> {
return (value: unknown) => {
if (typeof value !== 'object' || value === null) {
return { valid: false, error: 'Expected object' };
}
const result = {} as InferSchema<T>;
for (const key in schema) {
const validator = schema[key];
const fieldResult = validator((value as any)[key]);
if (!fieldResult.valid) {
return fieldResult;
}
result[key] = fieldResult.value;
}
return { valid: true, value: result };
};
}
// 使用
const userValidator = createValidator({
name: (value: unknown) =>
typeof value === 'string' && value.length > 0
? { valid: true, value }
: { valid: false, error: 'Invalid name' },
age: (value: unknown) =>
typeof value === 'number' && value >= 0
? { valid: true, value }
: { valid: false, error: 'Invalid age' }
});
type User = InferSchema<typeof userValidator>; // { name: string; age: number }
// 避免深度递归
// ❌ 性能差的深度递归
type DeepKeys<T> = T extends object
? { [K in keyof T]: K | DeepKeys<T[K]> }[keyof T]
: never;
// ✅ 使用迭代方式或限制深度
type DeepKeysLimited<T, Depth extends number = 3> =
Depth extends 0 ? never :
T extends object
? { [K in keyof T]: K | DeepKeysLimited<T[K], Subtract<Depth, 1>> }[keyof T]
: never;
// 使用缓存优化复杂计算
namespace Cache {
export type Map = Map<string, any>;
}
function memoizeType<T extends (...args: any[]) => any>(
fn: T
): T {
const cache = new Map<string, ReturnType<T>>();
return ((...args: any[]) => {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
return result;
}) as T;
}