![](/img/trans.png)
[英]How to get value from object based on propertyName in Typescript?
[英]Typescript - How to get a subset of properties from an object into a variable based on an interface
我有一個 function 接收兩種類型的交集:
interface A {
propA: string;
}
interface B {
propB: number;
propC: boolean;
}
function C(props: A & B) {
}
現在,在 function 主體內部,我想從每個接口獲取僅包含屬性子集的對象; 所以我想知道 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 }"
}
You're after a function that iterates over a known set of property names - this can't be done in pure TypeScript because TypeScript uses type-erasure, so the runtime script has no-knowledge of what the set of property names is.
但是使用稱為自定義轉換器的 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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.