
在typescript的类型系统中,我们经常会遇到需要基于现有类型派生出新类型场景。一个常见的需求是,我们希望创建一个新类型,它拥有与某个现有对象类型完全相同的属性键,但所有这些属性的类型都被统一设置为 any。这种转换在处理动态数据、api响应或需要临时忽略类型检查的场景中非常有用。
考虑以下一个典型的类定义:
class Foo {
foo: string;
bar: number;
baz: Date;
}我们的目标是生成一个像 TransmutedFoo 这样的接口,它拥有 Foo 的所有属性键,但所有值类型均为 any:
interface TransmutedFoo {
foo: any;
bar: any;
baz: any;
}接下来,我们将介绍两种实现这种泛型转换的方法。
映射类型是TypeScript中一个非常强大的特性,它允许我们基于旧类型转换出新类型,通常通过遍历旧类型的属性键来完成。它的基本语法是 [Key in K]: Type,其中 K 是一个联合类型,表示要遍历的键集合。
要实现 Transmuted<T> 泛型,我们可以这样定义:
type Transmuted<T> = {
[Key in keyof T]: any;
};让我们分解一下这个定义:
将这个泛型应用到我们的 Foo 类上,可以得到预期的结果:
class Foo {
foo: string;
bar: number;
baz: Date;
constructor() {
this.foo = "";
this.bar = 0;
this.baz = new Date();
}
}
type Transmuted<T> = {
[Key in keyof T]: any;
};
type TransmutedFoo = Transmuted<Foo>;
// TransmutedFoo 的类型将是:{ foo: any; bar: any; baz: any; }这种方法非常灵活,不仅可以将属性类型统一设置为 any,还可以根据需要设置为其他类型,甚至进行更复杂的类型转换。
对于将所有属性类型统一设置为相同类型的特定场景,TypeScript提供了一个内置的工具类型 Record<Keys, Type>。这个工具类型专门用于构造一个对象类型,其属性键由 Keys 指定,所有属性值类型均为 Type。
Record 类型的定义实际上就是基于映射类型实现的:
type Record<K extends keyof any, T> = {
[P in K]: T;
};利用 Record,我们可以更简洁地实现 Transmuted<T> 泛型:
type Transmuted<T> = Record<keyof T, any>;
这里:
同样,将其应用到 Foo 类上:
class Foo {
foo: string;
bar: number;
baz: Date;
constructor() {
this.foo = "";
this.bar = 0;
this.baz = new Date();
}
}
type Transmuted<T> = Record<keyof T, any>;
type TransmutedFoo = Transmuted<Foo>;
// TransmutedFoo 的类型同样是:{ foo: any; bar: any; baz: any; }两种方法都能有效地实现将一个对象类型的属性键保留,但将其所有属性类型统一转换为 any 的目标。
在本文给出的特定场景中,由于所有属性都统一转换为 any,使用 Record<keyof T, any> 是一个非常优雅且推荐的解决方案,因为它更加简洁明了。然而,理解其底层原理(即映射类型)对于处理更复杂的TypeScript类型转换至关重要。掌握这些技术将显著提升你在TypeScript中进行类型操作的能力。
以上就是TypeScript教程:使用泛型和映射类型统一转换对象属性类型为any的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号