打字稿对象字段键一般
Typescript object fields keys generically
我有一个数据结构,其中包含各种不同类型的可选字段,必须单独获取并设置格式。格式化函数采用具体值。
我尝试做类似下面的最小工作示例的操作,但是 Property 'value' does not exist on type 'Data[P]'
.
出现错误
我明白为什么会出现这个问题,但我想解决这个问题。我的快速破解方法是将 data[idx][key]
转换为 Optional<T>
,但这可以在没有类型转换的情况下完成吗?
// In my code this is more complex, a simple `T | undefined` doesn't work.
type Optional<T> = { kind: 'none' } | { kind: 'value', value: T};
interface Data {
name: Optional<string>;
id: Optional<number>;
}
function computeIndex(): number {
// Some logic here
return 0;
}
// Format field `key` of `data` using `formatter`.
// Use default `def` if the value is `none`.
function printField<
P extends keyof Data,
T extends Data[P] extends Optional<infer V> ? V : never
>(data: Data[], key: P, formatter: (val: T) => string, def: T): string {
const idx = computeIndex();
const field = data[idx][key];
switch (field.kind) {
case 'none':
return formatter(def);
case 'value':
return formatter(field.value);
}
}
我认为目前没有免铸解决方案。
最终,TS 似乎无法从 field
声明中的 Optional<string> | Optional<number>
推断出 Optional<string | number>
,因此我们以 Optional<T>
的形式给予它额外的推动演员.
这是黑客攻击吗?如果您将其视为绕过 TS 检查器的推理限制,也许可以。如果它打开了输入错误值的大门,或者如果结果没有达到预期的效果,我会同意这是一个 hack
但最终结果与“非黑客”解决方案一样有效,因为它正确地对给定 key
的 formatter
进行了类型检查。而且我不明白转换如何导致错误类型的值通过。
我有一个数据结构,其中包含各种不同类型的可选字段,必须单独获取并设置格式。格式化函数采用具体值。
我尝试做类似下面的最小工作示例的操作,但是 Property 'value' does not exist on type 'Data[P]'
.
我明白为什么会出现这个问题,但我想解决这个问题。我的快速破解方法是将 data[idx][key]
转换为 Optional<T>
,但这可以在没有类型转换的情况下完成吗?
// In my code this is more complex, a simple `T | undefined` doesn't work.
type Optional<T> = { kind: 'none' } | { kind: 'value', value: T};
interface Data {
name: Optional<string>;
id: Optional<number>;
}
function computeIndex(): number {
// Some logic here
return 0;
}
// Format field `key` of `data` using `formatter`.
// Use default `def` if the value is `none`.
function printField<
P extends keyof Data,
T extends Data[P] extends Optional<infer V> ? V : never
>(data: Data[], key: P, formatter: (val: T) => string, def: T): string {
const idx = computeIndex();
const field = data[idx][key];
switch (field.kind) {
case 'none':
return formatter(def);
case 'value':
return formatter(field.value);
}
}
我认为目前没有免铸解决方案。
最终,TS 似乎无法从 field
声明中的 Optional<string> | Optional<number>
推断出 Optional<string | number>
,因此我们以 Optional<T>
的形式给予它额外的推动演员.
这是黑客攻击吗?如果您将其视为绕过 TS 检查器的推理限制,也许可以。如果它打开了输入错误值的大门,或者如果结果没有达到预期的效果,我会同意这是一个 hack
但最终结果与“非黑客”解决方案一样有效,因为它正确地对给定 key
的 formatter
进行了类型检查。而且我不明白转换如何导致错误类型的值通过。