gpt4 book ai didi

typescript - 基于 TypeScript 中的现有对象创建 TypeSafe 对象字面量

转载 作者:搜寻专家 更新时间:2023-10-30 21:36:24 26 4
gpt4 key购买 nike

考虑以下函数:

function keysToValuesClone<TObject extends {}>(keysAndValuesObj: TObject) {
const clone = Object.assign({}, keysAndValuesObj);

Object.keys(clone).forEach(key => clone[key] = key);

const frozen = Object.freeze(clone);

return (<any>frozen) as Readonly<{ // The `any` is regrettable... see below
[K in keyof typeof clone]: K
}>;
}

我可以像这样为这个函数提供一个对象字面量:

const myHeaders = keysToValuesClone({
'a property with spaces': '',
'and another': '',
});

生成的 myHeaders 将具有以下类型:

Readonly<{
'a property with spaces': "a property with spaces";
'and another': "and another";
}>

我喜欢这个函数的实用性,但是编写它在我脑海中提出了 2 个问题:

是否有可能丢失any

如果我将 keysToValuesClone 的最后一行更改为:

    return frozen as Readonly<{
[K in keyof typeof clone]: K
}>;

然后我遇到了以下错误:

Type 'Readonly<TObject & {}>' cannot be converted to type 'Readonly<{ [K in keyof (TObject & {})]: K; }>'.
Type '(TObject & {})[P]' is not comparable to type 'P'.

我已经尝试以多种不同的方式说服编译器在没有 any 类型断言的情况下允许此函数,但所有尝试都失败了。这是可以改进的吗?您能否说服编译器在不求助于 any 的情况下顺其自然?

是否可以创建一个类似的函数来从 string[] 构造此类型?

我很想写这段代码:

const myHeaders = keysToValuesUsingArray([
'a property with spaces',
'and another'
]);

即提供一个字符串数组并使其输出与上面相同。 Codewise 我可以这样实现:

function keysToValuesArray(keys: string[]) {
const obj = keys.reduce((objInTheMaking, key) => ({ [key]: key, ...objInTheMaking }), {});

return obj;
}

但这会生成 {} 类型。有没有办法在类型系统中为这里发生的事情提供线索?

我玩过 keyof/typeof/Tuple 等都无济于事。所以我的 friend 们我求助于你们。

教育我。


谢谢提香!

太棒了提香;非常感谢!我最终通过 Readonly 调整使用您的阵列解决方案;见下文:(我现在莫名其妙地爱上了 Object.freeze;这是我的果酱)

function keysToValuesArray<T extends string>(keys: T[]): Readonly<{ [P in T] : P}> {
const obj = keys.reduce((objInTheMaking, key) => ({ [key]: key, ...objInTheMaking }), {} );

const frozen = Object.freeze(obj);

return frozen as Readonly<{ [P in T] : P}>;
}

再次感谢!

最佳答案

如果我们使用泛型类型参数来表示字段名称,当然可以从 string 数组创建对象:

function keysToValuesArray<T extends string>(keys: T[]) : { [P in T] : P}{
const obj = keys.reduce((objInTheMaking, key) => ({ [key]: key, ...objInTheMaking }), {} );
return obj as { [P in T] : P};
}
const myHeaders2 = keysToValuesArray([
'a property with spaces',
'and another'
]);

为了避免转换为 any,您可以将 clone 直接键入为 any{ [n: string]:任何 } 但这不会好多少。在构建这些对象时,它们无论如何都不符合类型,因此没有太大区别。我通常对调用站点是类型安全的想法感到安慰,这更重要。

function keysToValuesClone<TObject extends {}>(keysAndValuesObj: TObject) {
const clone : { [n: string]: any } = Object.assign({}, keysAndValuesObj);

Object.keys(clone).forEach(key => clone[key] = key);

const frozen = Object.freeze(clone);

return frozen as Readonly<{
[K in keyof typeof clone]: K
}>;
}

关于typescript - 基于 TypeScript 中的现有对象创建 TypeSafe 对象字面量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51176206/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com