[英]Infer object types by sibling property - Typescript
Is it possible to assert properties of an object based on another property within that same object?是否可以根据同一 object 中的另一个属性断言 object 的属性?
But how can I infer the types for values
based on the value of type
property?但是如何根据type
属性的values
推断值的类型呢?
type StepKeys = "Test1" | "Test2";
interface objectMap {
"Test1": {
name: string
},
"Test2": {
age: number
}
};
interface Step<T extends StepKeys = StepKeys> {
type: T;
value: objectMap[T]
};
const steps: Record<string, Step> = {
"Step1": {
type: "Test1",
value: {
}
}
}
Here types for values
are a union of { name: string; } | { age: number; }
这里values
的类型是{ name: string; } | { age: number; }
{ name: string; } | { age: number; }
{ name: string; } | { age: number; }
. { name: string; } | { age: number; }
。
Is it possible to infer it's possible values?是否可以推断出它的可能值?
Hi should you want to effectively discriminate this union, the type parameter should not be a union, instead seek to "push" the union one type up.你好,如果你想有效地区分这个联合,类型参数不应该是一个联合,而是寻求将联合“推”到一种类型。 This is because we want each Step
type to have it's own unique type parameter, instead of the union of possible type parameters.这是因为我们希望每个Step
类型都有自己唯一的类型参数,而不是可能类型参数的联合。 So a small change, but accomplishes what you want.所以一个小的改变,但完成你想要的。
const steps: Record<string, Step<'Test1'> | Step<'Test2'>> = {
"Step1": {
type: "Test1",
value: {
// infer ?
age: 11,
// ^^^ correctly throws error
// Object literal may only specify known properties, and 'age' does not exist in type '{ name: string; }'.(2322)
name: 'test',
}
}
}
Using an indexed access map type you can create a discriminated union automatically if there are a lot more key/value pairs.使用索引访问 map 类型,如果有更多的键/值对,您可以自动创建可区分的联合。
type Steps = Record<string, {
[key in StepKeys]: Step<key>
}[StepKeys]>
The only way to achieve what you want isn't really good but it works.实现你想要的东西的唯一方法并不是很好,但它确实有效。 The problem is that you have to manually enter every key (which makes it impossible to make it generic or scalable).问题是你必须手动输入每个密钥(这使得它不可能通用或可扩展)。
interface PeoplePropsMap {
withName: {
name: string
},
withAge: {
age: number
}
};
type People =
{ type: 'withName', value: PeoplePropsMap['withName'] } |
{ type: 'withAge', value: PeoplePropsMap['withAge'] }
const steps: Record<string, People> = {
john: {
type: 'withAge',
value: {
age: 10
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.