
在 typescript 开发中,我们有时会遇到这样的需求:需要基于一个已有的对象类型(例如一个类的实例类型),创建一个新的类型,该新类型保留原有类型的所有属性键,但将其所有属性的值类型统一设置为 any。这种转换在某些动态处理或与非强类型数据交互的场景中非常有用。
例如,给定一个 Foo 类:
class Foo {
foo: string;
bar: number;
baz: Date;
constructor() {
this.foo = "";
this.bar = 0;
this.baz = new Date();
}
}我们的目标是定义一个泛型类型 Transmuted<T>,使其在应用于 Foo 时,能够生成如下的 TransmutedFoo 接口:
interface TransmutedFoo {
foo: any;
bar: any;
baz: any;
}接下来,我们将探讨两种实现这种泛型类型的方法。
映射类型是 TypeScript 中一项强大的功能,它允许我们以声明式的方式,基于现有类型创建新类型。其基本语法是 [Key in K]: Type;,其中 K 是一个联合类型,表示新类型中属性键的集合。
为了实现我们的目标,我们可以利用 keyof T 来获取类型 T 的所有属性键,然后将这些键映射到 any 类型。
/**
* Transmuted<T> 泛型类型
* 将输入类型 T 的所有属性键保留,并将其对应的属性值类型统一设置为 any。
* @template T - 任意对象类型
*/
type Transmuted<T> = {
[Key in keyof T]: any;
};代码解析:
应用示例:
class Foo {
foo: string;
bar: number;
baz: Date;
constructor() {
this.foo = "";
this.bar = 0;
this.baz = new Date();
}
}
// 使用映射类型定义 Transmuted
type Transmuted<T> = {
[Key in keyof T]: any;
};
// 应用 Transmuted 到 Foo 类型
type TransmutedFoo = Transmuted<Foo>;
// 验证 TransmutedFoo 的类型
// type TransmutedFoo = {
// foo: any;
// bar: any;
// baz: any;
// }
// 我们可以创建一个 TransmutedFoo 类型的对象
const myTransmutedFoo: TransmutedFoo = {
foo: "hello",
bar: 123,
baz: new Date()
};
console.log(myTransmutedFoo);TypeScript 提供了一系列实用的内置工具类型(Utility Types),Record<Keys, Type> 就是其中之一。Record 工具类型用于构造一个对象类型,其属性键由 Keys 指定,而所有属性值都具有相同的 Type。
Record 的定义实际上也是基于映射类型实现的:type Record<K extends keyof any, T> = { [P in K]: T; };。因此,它非常适合我们当前的需求。
我们可以将 keyof T 作为 Record 的第一个类型参数 Keys,将 any 作为第二个类型参数 Type。
/** * Transmuted<T> 泛型类型 (使用 Record 工具类型实现) * 将输入类型 T 的所有属性键保留,并将其对应的属性值类型统一设置为 any。 * @template T - 任意对象类型 */ type Transmuted<T> = Record<keyof T, any>;
代码解析:
应用示例:
class Foo {
foo: string;
bar: number;
baz: Date;
constructor() {
this.foo = "";
this.bar = 0;
this.baz = new Date();
}
}
// 使用 Record 工具类型定义 Transmuted
type Transmuted<T> = Record<keyof T, any>;
// 应用 Transmuted 到 Foo 类型
type TransmutedFoo = Transmuted<Foo>;
// 验证 TransmutedFoo 的类型
// type TransmutedFoo = {
// foo: any;
// bar: any;
// baz: any;
// }
const anotherTransmutedFoo: TransmutedFoo = {
foo: "world",
bar: true, // 即使原始类型是 number,这里也可以是 any
baz: null // 即使原始类型是 Date,这里也可以是 any
};
console.log(anotherTransmutedFoo);两种方法都能有效地实现将一个对象类型的所有属性值统一映射为 any 的目标。在实际开发中,如果目标是统一所有属性的类型,推荐使用 Record 工具类型,因为它更简洁明了。如果需要更精细或更复杂的类型转换逻辑,则应直接使用映射类型。理解这两种方法有助于您更灵活地处理 TypeScript 中的类型转换需求。
以上就是TypeScript 泛型实战:将对象属性统一映射为 any 的方法详解的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号