TypeScript中类型转换(Type Transformation)

在TypeScript中,类型转换(Type Transformation)是一个强大的功能,可以通过不同的方法将一种类型转换成另一种类型。以下是一些高级类型转换的示例:

1. 映射类型(Mapped Types)

映射类型可以通过在现有类型的基础上创建一个新类型。

type Person = {
  name: string;
  age: number;
};

// 将所有属性设为可选
type PartialPerson = {
  [P in keyof Person]?: Person[P];
};

// 将所有属性设为只读
type ReadonlyPerson = {
  readonly [P in keyof Person]: Person[P];
};

2. 条件类型(Conditional Types)

条件类型允许你根据条件生成不同的类型。

type IsString<T> = T extends string ? 'yes' : 'no';

type Test1 = IsString<string>;  // 'yes'
type Test2 = IsString<number>;  // 'no'

3. 提取和排除类型(Extract and Exclude)

ExtractExclude用于从联合类型中提取或排除子类型。

type Union = string | number | boolean;

// 提取字符串和数字类型
type StringOrNumber = Extract<Union, string | number>;  // string | number

// 排除布尔类型
type NotBoolean = Exclude<Union, boolean>;  // string | number

4. 内置的类型工具(Utility Types)

TypeScript 提供了一些内置的类型工具来简化常见的类型转换。

type Person = {
  name: string;
  age: number;
  address?: string;
};

// 将所有属性设为可选
type PartialPerson = Partial<Person>;

// 将所有属性设为只读
type ReadonlyPerson = Readonly<Person>;

// 从类型中选取部分属性
type NameAndAge = Pick<Person, 'name' | 'age'>;

// 排除某些属性
type AddresslessPerson = Omit<Person, 'address'>;

5. 索引类型查询和访问(Index Types)

索引类型查询和访问允许你动态地获取和操作类型中的属性。

type Person = {
  name: string;
  age: number;
};

// 获取属性类型
type NameType = Person['name'];  // string

// 动态获取属性类型
type PropertyType<T, K extends keyof T> = T[K];
type AgeType = PropertyType<Person, 'age'>;  // number

6. 映射联合类型(Mapped Union Types)

通过映射联合类型,可以创建更复杂的类型转换。

type Status = 'success' | 'error' | 'loading';

type StatusMessages = {
  [K in Status]: K extends 'success' ? 'Operation was successful' : 
                  K extends 'error' ? 'There was an error' : 
                  'Loading...';
};

// StatusMessages 的类型
// {
//   success: 'Operation was successful',
//   error: 'There was an error',
//   loading: 'Loading...'
// }

7. 递归类型(Recursive Types)

递归类型允许你定义自引用的类型。

type Tree<T> = {
  value: T;
  children?: Tree<T>[];
};

const tree: Tree<string> = {
  value: 'root',
  children: [
    { value: 'child1' },
    { value: 'child2', children: [{ value: 'grandchild1' }] }
  ]
};

8. 交叉类型(Intersection Types)

交叉类型可以将多个类型合并为一个类型。

type A = { a: number };
type B = { b: string };

type C = A & B;

const c: C = { a: 1, b: 'hello' };

这些高级类型转换技巧可以帮助你在TypeScript中创建更灵活和强大的类型定义。

9. 类型推断(Type Inference)

在条件类型中可以使用 infer 关键字进行类型推断。

type ElementType<T> = T extends (infer U)[] ? U : T;

type StringType = ElementType<string[]>; // string
type NumberType = ElementType<number>;   // number

10. 分布式条件类型(Distributive Conditional Types)

条件类型默认在联合类型上是分布式的。

type ToArray<T> = T extends any ? T[] : never;

type StringArray = ToArray<string>;   // string[]
type NumberArray = ToArray<number>;   // number[]
type UnionArray = ToArray<string | number>; // string[] | number[]

11. 元组与数组转换(Tuple and Array Transformation)

你可以通过条件类型和映射类型在元组和数组之间进行转换。

type TupleToUnion<T> = T extends (infer U)[] ? U : never;

type UnionFromTuple = TupleToUnion<[string, number, boolean]>; // string | number | boolean

type ArrayToTuple<T extends any[]> = { [K in keyof T]: T[K] };

type TupleType = ArrayToTuple<[string, number, boolean]>; // [string, number, boolean]

12. 条件类型中的类型推断

通过 infer 可以在条件类型中推断类型的一部分。

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

type Func = () => string;
type FuncReturnType = ReturnType<Func>; // string

13. 模式匹配与提取(Pattern Matching and Extraction)

在条件类型中,可以通过模式匹配提取出类型的一部分。

type GetFirstArgType<T> = T extends (arg1: infer U, ...args: any[]) => any ? U : never;

type FunctionType = (arg1: string, arg2: number) => void;
type FirstArgType = GetFirstArgType<FunctionType>; // string

14. 推断元组长度(Infer Tuple Length)

可以通过递归条件类型推断元组的长度。

type LengthOfTuple<T extends any[], L extends any[] = []> = T extends [infer First, ...infer Rest]
  ? LengthOfTuple<Rest, [First, ...L]>
  : L['length'];

type Length = LengthOfTuple<[string, number, boolean]>; // 3

15. 递归类型与类型运算(Recursive Types and Type Operations)

你可以通过递归类型和类型运算实现复杂的类型变换。

type DeepReadonly<T> = {
  readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P];
};

type NestedObject = {
  a: {
    b: {
      c: string;
    };
  };
};

type ReadonlyNestedObject = DeepReadonly<NestedObject>;
// {
//   readonly a: {
//     readonly b: {
//       readonly c: string;
//     };
//   };
// }

16. 类型守卫(Type Guards)

类型守卫用于在运行时判断类型,并在编译时进行类型缩小。

function isString(value: any): value is string {
  return typeof value === 'string';
}

function example(value: string | number) {
  if (isString(value)) {
    console.log(value.toUpperCase()); // 在此分支中,value 被推断为 string
  } else {
    console.log(value.toFixed()); // 在此分支中,value 被推断为 number
  }
}

17. 高级泛型用法(Advanced Generics)

通过泛型实现更灵活的类型。

type Filter<T, U> = T extends U ? T : never;

type NumbersOnly = Filter<string | number | boolean, number>; // number

type NonNullable<T> = T extends null | undefined ? never : T;

type NonNullableType = NonNullable<string | number | null | undefined>; // string | number

18. 联合类型分布式条件(Distributive Conditional Types)

在联合类型上使用条件类型会自动进行分布计算,这是 TypeScript 类型系统的一大特性。

type NonNullable<T> = T extends null | undefined ? never : T;

type Result = NonNullable<string | number | undefined>; // string | number

19. 模板字面量类型(Template Literal Types)

模板字面量类型允许你基于字符串模板生成新的类型。

type EventName<T extends string> = `${T}Changed`;

type ClickEvent = EventName<'click'>;  // "clickChanged"
type FocusEvent = EventName<'focus'>;  // "focusChanged"

20. 映射元组类型(Mapped Tuple Types)

可以对元组类型进行映射,从而生成新的元组类型。

type MapToPromise<T> = {
  [P in keyof T]: Promise<T[P]>;
};

type Tuple = [number, string, boolean];
type PromiseTuple = MapToPromise<Tuple>; // [Promise<number>, Promise<string>, Promise<boolean>]

21. 符合键类型(Compound Key Types)

可以组合多个键来生成新的类型。

type NestedKeys<T> = {
  [K in keyof T]: T[K] extends object ? `${K & string}.${NestedKeys<T[K]>}` : K & string
}[keyof T];

type Person = {
  name: string;
  address: {
    street: string;
    city: string;
  };
};

type Keys = NestedKeys<Person>; // "name" | "address.street" | "address.city"

22. 联合类型的差集(Difference of Union Types)

计算两个联合类型之间的差集。

type Diff<T, U> = T extends U ? never : T;

type A = 'a' | 'b' | 'c';
type B = 'b' | 'c' | 'd';

type Difference = Diff<A, B>; // "a"

23. 组合条件类型(Combination of Conditional Types)

组合条件类型可以实现复杂的类型逻辑。

type IsNever<T> = [T] extends [never] ? true : false;
type IsUnion<T> = T extends any ? ([T] extends [T] ? false : true) : never;

type TestNever = IsNever<never>; // true
type TestUnion = IsUnion<string | number>; // true
type TestNonUnion = IsUnion<string>; // false

24. 索引签名(Index Signatures)

索引签名允许你定义具有动态键的对象类型。

type Dictionary<T> = {
  [key: string]: T;
};

type StringDictionary = Dictionary<string>;

const example: StringDictionary = {
  key1: "value1",
  key2: "value2"
};

25. 类型保护(Type Guards)

类型保护用于在代码中进行类型的缩小,从而在特定代码块中得到更准确的类型。

function isNumber(value: any): value is number {
  return typeof value === 'number';
}

function example(value: string | number) {
  if (isNumber(value)) {
    console.log(value.toFixed()); // value 被推断为 number
  } else {
    console.log(value.toUpperCase()); // value 被推断为 string
  }
}

26. 索引访问类型(Indexed Access Types)

索引访问类型允许你从对象类型中提取某个属性的类型。

type Person = {
  name: string;
  age: number;
};

type NameType = Person['name']; // string
type AgeType = Person['age'];   // number

27. 类型别名(Type Aliases)

类型别名允许你为复杂的类型定义一个简短的名字。

type Point = {
  x: number;
  y: number;
};

type Point3D = Point & {
  z: number;
};

const point: Point3D = { x: 1, y: 2, z: 3 };

28. 泛型约束(Generic Constraints)

泛型约束允许你对泛型参数进行限制。

function identity<T extends number | string>(value: T): T {
  return value;
}

const num = identity(42);  // 42
const str = identity("Hello");  // "Hello"

29. 高阶类型(Higher-order Types)

高阶类型是指接受类型参数并返回新类型的类型。

type WithId<T> = T & { id: string };

type User = {
  name: string;
  age: number;
};

type UserWithId = WithId<User>; // { name: string; age: number; id: string }

30. 构造签名(Constructor Signatures)

构造签名用于定义类的构造函数类型。

interface Constructable<T> {
  new (...args: any[]): T;
}

class Person {
  constructor(public name: string) {}
}

function createInstance<T>(ctor: Constructable<T>, ...args: any[]): T {
  return new ctor(...args);
}

const person = createInstance(Person, 'John'); // Person { name: 'John' }

这些高级用法展示了 TypeScript 类型系统的强大和灵活性。通过这些技巧,你可以在项目中实现更强的类型安全和更好的代码提示。

  • 12
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值