在typescript中,有没有办法通过修改另一个属性名来动态生成属性名?
我正在尝试为React高阶组件编写一些类型,用于修改传递给包装组件的属性。如果您为hoc配置了一个属性名称(例如,value),它也会从中生成一个属性名称(在本例中为defaultValue)。
Typescript playground上的部分工作代码示例。
理想情况下,尝试访问defaultValue时不会出现错误。
发布于 2021-02-01 06:35:28
当您问这个问题时,这是不可能的,但现在随着typescript版本4.1中Template Literal Types的引入,这是可能的。
我们定义了一个从字符串文字"name“映射到其对应的"defaultName”的类型。
type DefaultName<PropName extends string> = `default${Capitalize<PropName>}`我们声明Props应该同时具有属性值和默认值。
type Props<PropName extends string, Value = boolean> = {
[K in PropName]: Value;
} & {
[K in DefaultName<PropName>]: Value;
}我将字符串的操作转移到一个单独的函数中,该函数为它创建的字符串文字断言正确的返回类型。(尽管从技术上讲,由于as Props<PropName>,hoc在没有此断言的情况下工作)。
function computeName<T extends string>(name: T): DefaultName<T> {
const computedName = 'default' + name.slice(0, 1).toUpperCase() + name.slice(1);
// need to assert the return type here, otherwise it's just `string`
return computedName as DefaultName<T>;
}你的hoc基本上是一样的。在调用fn时,我们仍然需要断言as Props<PropName>,否则对象会被解释为{ [x: string]: boolean; }。
function hoc<PropName extends string>(config: Config<PropName>, fn: Callback<PropName>) {
fn({
[config.name]: true,
[computeName(config.name)]: false
} as Props<PropName>);
}魔术发生在test中,现在众所周知,obj有一个obj.defaultValue属性。这修复了您之前遇到的错误。
const test = hoc({ name: 'value' }, (obj) => {
console.log(obj.value, obj.defaultValue); // no more errors
});https://stackoverflow.com/questions/58089041
复制相似问题