TypeScript:从其他字符串文字联合类型限制区分联合中的鉴别器
TypeScript: Limit discriminator in discriminated union from other string literal union type
我有一个非常基本的判别联合,但对于判别器,我只想允许来自另一个字符串文字联合类型的特定值。这将使向受歧视的联合添加新的联合“案例”变得更加容易。
这是一个字符串文字联合,它描述了该类型允许的“值”:
type AllowedType = "typeForNumber" | "typeForBoolean"
然后,我描述数据的类型使用该字符串文字联合:
type Data = {
type: AllowedType,
value: number | boolean
}
根据我的示例,有两个选项,可以根据 type
字段为 value
指定更具体的类型。我不使用这些选项,它们只是用于演示目的:
// Option 1 - "value" is a "number"
type DataOption1 = {
type: "typeForNumber",
value: number
}
// Option 2 - "value" is a "boolean"
type DataOption2 = {
type: "typeForBoolean",
value: boolean
}
所以我真正想做的是 Data
的可区分联合,因为这样我可以为其 value
字段提供更具体的类型:
type Data =
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
}
当你使用类型时,一切正常:
const myData: Data = {
type: "typeForNumber",
// this creates an error, should be a `number`
value: "some string"
}
我的问题是:如何确保我的 Data
类型中的 type
字段只能是 AllowedType
的选项之一?
以后AllowedType
会有更多的选择,所以我想用它们限制可能的联合类型。
可以像这样更改添加另一个联合到 Data
类型,没有任何错误:
type Data =
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
}
| {
type: "someOtherType"
value: string
}
不应允许这个新联合(与 type: "someOtherType"
)。
是否可以从其他字符串文字联合类型 (AllowedType
) 中限制此已区分联合 (Data
) 中的鉴别器 (type
)?
我尝试对交集使用包装器,但联合会忽略(覆盖?)type
类型:
type AllowedType = "typeForNumber" | "typeForBoolean"
type DataWrapper = {
type: AllowedType
value: number | boolean
}
type Data = DataWrapper &
(
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
}
)
如果我理解正确,问题是 Data
和 AllowedType
可能不同步。如果这是问题所在,您可以扭转局面,根据 Data
定义 AllowedType
,如下所示:
type Data =
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
};
type AllowedType = Data["type"];
然后,添加到 Data
会自动添加到 AllowedType
。
在评论中,您曾说过您正在努力防止 Data
联盟的 type
中的拼写错误:
In my case, the Data type represents dynamic data coming from another source, so I want to be sure that there are e.g. no typos in the type values (like typeForNumber). That's why I'm so keen to find a solution to limit the type to specific values. Turning it around doesn't help in my case.
这似乎对此有所帮助:
type CheckData<DataType extends {type: AllowedType}> =
Exclude<DataType["type"], AllowedType> extends never
? DataType
: never;
然后这个有效:
type Data = CheckData<
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
}>;
但这不是:
type Data2 = CheckData<
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
}
| {
type: "typeForSomethingElse"
value: boolean
}>;
不过,它不会捕捉到 所有 错别字。它允许两种类型都使用相同的 type
值。
我有一个非常基本的判别联合,但对于判别器,我只想允许来自另一个字符串文字联合类型的特定值。这将使向受歧视的联合添加新的联合“案例”变得更加容易。
这是一个字符串文字联合,它描述了该类型允许的“值”:
type AllowedType = "typeForNumber" | "typeForBoolean"
然后,我描述数据的类型使用该字符串文字联合:
type Data = {
type: AllowedType,
value: number | boolean
}
根据我的示例,有两个选项,可以根据 type
字段为 value
指定更具体的类型。我不使用这些选项,它们只是用于演示目的:
// Option 1 - "value" is a "number"
type DataOption1 = {
type: "typeForNumber",
value: number
}
// Option 2 - "value" is a "boolean"
type DataOption2 = {
type: "typeForBoolean",
value: boolean
}
所以我真正想做的是 Data
的可区分联合,因为这样我可以为其 value
字段提供更具体的类型:
type Data =
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
}
当你使用类型时,一切正常:
const myData: Data = {
type: "typeForNumber",
// this creates an error, should be a `number`
value: "some string"
}
我的问题是:如何确保我的 Data
类型中的 type
字段只能是 AllowedType
的选项之一?
以后AllowedType
会有更多的选择,所以我想用它们限制可能的联合类型。
可以像这样更改添加另一个联合到 Data
类型,没有任何错误:
type Data =
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
}
| {
type: "someOtherType"
value: string
}
不应允许这个新联合(与 type: "someOtherType"
)。
是否可以从其他字符串文字联合类型 (AllowedType
) 中限制此已区分联合 (Data
) 中的鉴别器 (type
)?
我尝试对交集使用包装器,但联合会忽略(覆盖?)type
类型:
type AllowedType = "typeForNumber" | "typeForBoolean"
type DataWrapper = {
type: AllowedType
value: number | boolean
}
type Data = DataWrapper &
(
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
}
)
如果我理解正确,问题是 Data
和 AllowedType
可能不同步。如果这是问题所在,您可以扭转局面,根据 Data
定义 AllowedType
,如下所示:
type Data =
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
};
type AllowedType = Data["type"];
然后,添加到 Data
会自动添加到 AllowedType
。
在评论中,您曾说过您正在努力防止 Data
联盟的 type
中的拼写错误:
In my case, the Data type represents dynamic data coming from another source, so I want to be sure that there are e.g. no typos in the type values (like typeForNumber). That's why I'm so keen to find a solution to limit the type to specific values. Turning it around doesn't help in my case.
这似乎对此有所帮助:
type CheckData<DataType extends {type: AllowedType}> =
Exclude<DataType["type"], AllowedType> extends never
? DataType
: never;
然后这个有效:
type Data = CheckData<
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
}>;
但这不是:
type Data2 = CheckData<
| {
type: "typeForNumber"
value: number
}
| {
type: "typeForBoolean"
value: boolean
}
| {
type: "typeForSomethingElse"
value: boolean
}>;
不过,它不会捕捉到 所有 错别字。它允许两种类型都使用相同的 type
值。