Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js 摘录;定义为;在运行时从TypeScript中的属性键入 我想做什么_Node.js_Typescript_Types - Fatal编程技术网

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}