reactjs - Typescript - 如何将对象的属性子集获取到基于接口的变量中
问题描述
我有一个接收两种类型交集的函数:
interface A {
propA: string;
}
interface B {
propB: number;
propC: boolean;
}
function C(props: A & B) {
}
现在,在函数体内,我想从每个接口获取仅包含属性子集的对象;所以我想知道 Typescript 是否有任何实用程序来实现这一点:
function C(props: A & B) {
const a = fancyPicker<A>(props);
const b = fancyPicker<B>(props);
console.log(a);
// prints "{ propA: "some string" }"
console.log(b);
// prints "{ propB: 42, propC: false }"
}
解决方案
您正在使用迭代一组已知属性名称的函数 - 这不能在纯 TypeScript 中完成,因为 TypeScript 使用类型擦除,因此运行时脚本不知道属性名称集是什么。
但是使用称为自定义转换器的 TypeScript 编译时扩展,特别ts-transformer-keys
是 TypeScript 编译器将发出可以使用的属性名称列表。
这里有一些可行的方法,但并不完美,因为它不使用每个属性的类型——它只匹配名称:
import { keys } from 'ts-transformer-keys'; // <-- This module is where the magic happens.
type IndexableObject = {
[key: string]: any
};
/*
* The `IndexableObject` above is a hack. Note it allows `any` property type. Ideally it'd be something like this instead, but using `keyof` in a type indexer is not yet supported: https://github.com/microsoft/TypeScript/pull/26797
*
type IndexableObject<TOther> = {
[key: TKey extends keyof TOther]: PropertyType<TOther,TKey>
};
*/
function fancyPicker<TSubset extends object>(superset: IndexableObject): Partial<TSubset> {
const subsetPropertyNames = keys<TSubset>();
const ret: Partial<TSubset> = {
};
for (const subsetPropertyName of subsetPropertyNames) {
const propName: string = subsetPropertyName as string; // <-- This is also a hack because property keys/names are actually `string | number | symbol` - but this function assumes they're all named properties.
if (propName in superset) {
const value = superset[propName];
ret[subsetPropertyName] = value;
}
}
return ret;
}
用法(使用您的示例):
interface A {
propA: string;
}
interface B {
propB: number;
propC: boolean;
}
type ABIntersection = A & B;
type ABUnion = A | B;
function C(props: ABIntersection) {
const a = fancyPicker<A>(props);
const b = fancyPicker<B>(props);
console.log(a);
// prints "{ propA: "some string" }"
console.log(b);
// prints "{ propB: 42, propC: false }"
}
const testValue = { propA: "some string", propB: 42, propC: false, propD: "never see this" };
C(testValue);
推荐阅读
- javascript - 为什么 webpack 找不到 scss 文件
- java - 尝试从输入框获取密码时出错
- rotation - OpenVR Teleportation Problem(前向计算)
- angular - Angular Google Maps 组件图标不起作用
- google-drive-api - 验证不允许 HEAD 时 URL 中是否存在图像
- python - 即使在用新代码替换代码后,Flask 也会继续执行相同的旧代码
- c - uint64_t 到 va_list 的错误传递
- api - 如何在flutter中使用rest api在下拉列表中显示数据
- wpf - WPF WrapPanel,但由于不同大小的项目而填充空白空间?
- python - (sqlite3.OperationalError) 没有这样的表