Node.js 摘录;定义为;在运行时从TypeScript中的属性键入 我想做什么
我目前正在循环一个对象的键,并将值传输到另一个对象Node.js 摘录;定义为;在运行时从TypeScript中的属性键入 我想做什么,node.js,typescript,types,Node.js,Typescript,Types,我目前正在循环一个对象的键,并将值传输到另一个对象 interface From { [key: string]: string; } let from: From = { prop1: "foo", prop2: "23", }; interface To { [key: string]: string | number | boolean | undefined; prop1: string; prop2: number; prop
interface From {
[key: string]: string;
}
let from: From = {
prop1: "foo",
prop2: "23",
};
interface To {
[key: string]: string | number | boolean | undefined;
prop1: string;
prop2: number;
prop3: boolean;
}
let to: To = {} as To;
const initEnv = async () => {
const keys: string[] = Object.keys(from);
for (let i = 0; i < keys.length; i++) {
let key: string = keys[i];
let keyType = typeof (key as keyof To); // This only returns "string". Which kind of makes sense to me
let keyType = typeof keyof key; // SyntaxError: ',' expected
let keyType: typeof to[key]; // Error: 'key' refers to a value, but is being used as a type
to[key] = from[key];
}
};
也许吧,但问题是;我应该给这个变量赋值什么
之所以这样做,是因为我想将从变量
转换为正确的类型,将它们分配给to
对象
所以,基本上,我的问题是如何从键中提取类型(作为字符串,在运行时,动态地)。或者一开始就有可能吗?如果不是,为什么不呢?我喜欢理解事物
也谢谢你忍受我糟糕的英语 运行时没有接口
s;TypeScript的类型系统来自发出的JavaScript。您的from
和to
值将在运行时进行如下评估:
let from = {
prop1: "foo",
prop2: "23",
};
let to = {};
没有From
或To
,也没有办法使用To
来找出如何将从
的属性强制转换为正确的类型。类型系统没有运行时效果
TypeScript类型系统的有用性来自于描述运行时将发生的事情,而不是在运行时影响事情。想象一下,您必须如何用纯JavaScript编写代码,然后为代码提供类型。我有一个办法可以做到。与其使用To
接口,不如创建一个To
对象,其属性是将输入强制为其他类型的函数:
const To = {
prop1: String,
prop2: Number,
prop3: Boolean
}
这些信息足以在运行时继续
现在,如果您要手动将构建为,编译器将能够理解结果值具有prop1
类型string
的属性和prop2
类型number
的属性:
const toManual = { prop1: To.prop1(from.prop1), prop2: To.prop2(from.prop2) };
/* const toManual: { prop1: string; prop2: number; } */
但你不想手动操作;您希望编写一个循环,遍历from
的键,并使用to
生成to
的属性。编译器更难理解这一点,但通过明智地使用和类型注释,您可以编写一个以编程方式工作的objMap
函数:
function objMap<T, F extends { [K in keyof T]: (arg: T[K]) => any }>(
obj: T, fMap: F) {
const ret = {} as { [K in keyof T]: ReturnType<F[K]> };
const fM: { [K in keyof T]: (arg: T[K]) => ReturnType<F[K]> } = fMap;
(Object.keys(obj) as Array<keyof T>).forEach(<K extends keyof T>(k: K) => {
ret[k] = fM[k](obj[k]);
})
return ret;
}
这看起来是正确的;编译器将to
的类型推断为{prop1:string,prop2:number}
,to
的实际值在运行时计算为{prop1:“foo”,prop2:23}
好吧,希望这会有帮助;祝你好运
天哪!你花了多长时间才想到这个?我花了20分钟才明白。非常感谢你!这是完美的,绝对可以。
function objMap<T, F extends { [K in keyof T]: (arg: T[K]) => any }>(
obj: T, fMap: F) {
const ret = {} as { [K in keyof T]: ReturnType<F[K]> };
const fM: { [K in keyof T]: (arg: T[K]) => ReturnType<F[K]> } = fMap;
(Object.keys(obj) as Array<keyof T>).forEach(<K extends keyof T>(k: K) => {
ret[k] = fM[k](obj[k]);
})
return ret;
}
const to = objMap(from, To);
/* const to: { prop1: string; prop2: number; } */
console.log(JSON.stringify(to));
// {"prop1":"foo","prop2":23}