打字稿中是否可以通过修改另一个属性名称来动态生成属性名称?
我正在尝试为React高阶组件编写一些类型,以修改传递给包装组件的道具。如果您为hoc配置了属性名称(例如value
),它还将从中生成属性名称(在这种情况下为defaultValue
)。
Typescript playground上的部分工作代码示例。
理想情况下,尝试访问defaultValue
时不会出错。
答案 0 :(得分:0)
当您问这个问题时,这是不可能的,但现在可以在 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
基本相同。我们仍然需要在调用 as Props<PropName>
时断言 fn
,否则对象将被解释为 { [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
});