打字稿:通过键入

时间:2020-10-04 15:27:40

标签: typescript typescript-generics

我有时会使用一个小工具func(js),我很喜欢这样输入:

// original js untypified
function prefixProperties(obj, prefix) {
    let out = {};
    for (let propt in obj) {
        out[prefix + propt] = obj[propt];
    }
    return out;
}

let x : { num: number, date: Date } = { ... };
let y = prefixProperties(x, 'old');
/*
be great if typeof y was:
{
    oldnum: number,
    olddate: Date,
};
*/

或者最具体的就是这种功能。

我考虑过元组映射,但是我猜想它们不允许您更改键名。

{
    [K in keyof T]: whatever
};

1 个答案:

答案 0 :(得分:11)

您很幸运。虽然在当前版本的打字稿中无法实现,但很快就会实现。 Typescript 4.1(将于2020年11月发布)将添加对Template literal types and mapped type 'as' clauses的支持。使用此新功能,您可以编写:

type PrefixAll<T, P extends string>  = {
    [K in keyof T & string as `${P}${K}`]: T[K]
}

function prefixProperties<T, P extends string>(obj: T, prefix: P): PrefixAll<T, P> {
    let out = {} as Record<string, unknown>;
    for (let propt in obj) {
        out[prefix + propt] = obj[propt];
      }
    return out as PrefixAll<T, P>;
}

let x : { num: number, date: Date } = { ... };
let y = prefixProperties(x, 'old');

y.olddate
y.oldnum

Playground Link

当前无法使用的部分是as `${P}${K}` 。这部分将使用模板文字类型将P(前缀)连接到当前属性K,并且as子句将使连接的结果成为结果中的新属性对象而不是K

您甚至可以将道具名称大写以获取oldNameoldDate,在我看来,这样更好:

type PrefixAll<T, P extends string>  = {
    [K in keyof T & string as `${P}${Capitalize<K>}`]: T[K]
}

Playground Link

注意:我更改为前缀,而不是后缀,因为这是您在最后指定的转换,但是后缀很简单,只需将模板文字类型更改为$ {K} $ {P}