当TypeScript编译为JavaScript时,类型信息(包括接口)被清除。因此,您无法在运行时参考MoneyHolder
,以列举您关心的id
和money
键。
什么你可以要做的就是创建你所关心的按键阵列,并且打字稿可以使用数组的类型推断一个类型MoneyHolder
你。以下是如何获得打字稿推断字符串常量数组:
function stringLiteralArray<K extends string>(...arr: K[]): K[] {
return arr;
}
const moneyHolderKeys = stringLiteralArray('id', 'money');
助手功能stringLiteralArray()
做推理为您服务。
(旁白)
如果你只是这样做:
const moneyHolderKeysOops = ['id', 'money']; // string[]
它会被推断为string[]
其失去你关心的关键信息。你可以这样做:
const moneyHolderKeysTedious = ['id', 'money'] as ('id'|'money')[];
但这是繁琐和重复。这就是为什么我们创建了stringLiteralArray()
辅助函数。
所以,现在你有moneyHolderKeys
阵列与推断类型的('id' | 'money')[]
。这里是你如何编写一般的克隆功能:
function clonePart<T, K extends keyof T>(keys: K[], obj: T): Pick<T, K> {
const ret = {} as Pick<T, K>;
keys.forEach(k => ret[k] = obj[k]);
return ret;
}
注意的返回值,Pick<T,K>
这是T
仅指定的K
键的超类型。这是标准的打字稿库的一部分,它的定义是:
/**
* From T pick a set of properties K
*/
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
现在你可以使用它:
let person = new Person(1, 'Jack', 100);
let holder = clonePart(moneyHolderKeys, person);
如果检查holder
,你会看到它是{id: number, money: number}
类型。嘿,那是MoneyHolder
!我们现在可以命名它,如果你想:
type MoneyHolder = typeof holder;
因此,工程。这与你所要求的有点背道而驰,但它可以在没有任何重复的情况下完成工作。你可以see it in action in the TypeScript Playground。希望有所帮助;祝你好运!
1)我需要通过HTTP发送数据来消除其他属性2)keyof是在运行时使用接口类型信息的完美示例https://www.typescriptlang.org/docs/handbook/release-notes/打字稿-2-1.html – Rem
我敢肯定,问题是要求一个新的对象与原始对象的相关属性的副本。我也怀疑这个问题意味着*每个*属性(包括'name')都应该被复制,但我可能是错的。 – jcalz
@Rem但'keyof'不允许你在运行时做任何事情。它只存在于设计时。如果你检查编译过的JavaScript,那里就不会有任何对应'keyof'的东西。 – jcalz