在打字稿中构建映射的独占类型
Building mapped exclusive type in typescript
我有以下类型(简体):
type ValueRepresents = {
boolean: true
number?: false
other?: false
} |
{
boolean?: false
number: true
other?: false
} |
{
boolean?: false
number?: false
other: true
}
我的实际类型有更多可能的键。有没有一种方法可以从可能的键列表中生成这种类型,以使其仅在一个键的值设置为 true 时有效?类似于:
type ValueTypes = "boolean" | "number" | "other"
type ValueRepresents <T extends ValueTypes> = {
[k in ValueTypes]: k extends T ? true : false
}
const a: ValueRepresents<"boolean"> = {
boolean: true,
number: false,
other: false,
}
但我的目标是能够使用:
// should pass
const a: ValueRepresents = { boolean: true }
// should pass
const a2: ValueRepresents = {
boolean: true,
number: false,
}
// should error
const a3: ValueRepresents = {
boolean: true,
number: true,
}
// should error
const a4: ValueRepresents = {}
我也试过 但还没有成功:
type ValueRepresents <T extends ValueTypes> = {
[k in Exclude<T, ValueTypes>]?: false
} & { [k in T]: true }
您可以尝试创建这样的联合类型
type ValueTypes = "boolean" | "number" | "other"
type ValueRepresents = ({
[K in ValueTypes]: Partial<Record<Exclude<ValueTypes, K>, false>> & Record<K, true>
})[ValueTypes]
TL;DR
我认为这个表达式没有特定的名称。我在 the docs in Advanced Types 中看到过类似的示例,但我会尝试解释它是如何工作的。
type ValueRepresents = {
[K in ValueTypes]: Partial<Record<Exclude<ValueTypes, K>, false>> & Record<K, true>
}
创建的类型等效于:
type ValueRepresents = {
boolean: {
boolean: true;
number?: false;
other?: false;
};
number: {
boolean?: false;
number: true;
other?: false;
};
other: {
boolean?: false;
number?: true;
other: true;
};
};
并通过在方括号 [ValueTypes]
中添加联合类型,它提取了另一个联合类型中的那些(所有)键的值,等同于:
type ValueRepresents =
| {
boolean: true;
number?: false;
other?: false;
}
| {
boolean?: false;
number: true;
other?: false;
}
| {
boolean?: false;
number?: true;
other: true;
};
我有以下类型(简体):
type ValueRepresents = {
boolean: true
number?: false
other?: false
} |
{
boolean?: false
number: true
other?: false
} |
{
boolean?: false
number?: false
other: true
}
我的实际类型有更多可能的键。有没有一种方法可以从可能的键列表中生成这种类型,以使其仅在一个键的值设置为 true 时有效?类似于:
type ValueTypes = "boolean" | "number" | "other"
type ValueRepresents <T extends ValueTypes> = {
[k in ValueTypes]: k extends T ? true : false
}
const a: ValueRepresents<"boolean"> = {
boolean: true,
number: false,
other: false,
}
但我的目标是能够使用:
// should pass
const a: ValueRepresents = { boolean: true }
// should pass
const a2: ValueRepresents = {
boolean: true,
number: false,
}
// should error
const a3: ValueRepresents = {
boolean: true,
number: true,
}
// should error
const a4: ValueRepresents = {}
我也试过
type ValueRepresents <T extends ValueTypes> = {
[k in Exclude<T, ValueTypes>]?: false
} & { [k in T]: true }
您可以尝试创建这样的联合类型
type ValueTypes = "boolean" | "number" | "other"
type ValueRepresents = ({
[K in ValueTypes]: Partial<Record<Exclude<ValueTypes, K>, false>> & Record<K, true>
})[ValueTypes]
TL;DR
我认为这个表达式没有特定的名称。我在 the docs in Advanced Types 中看到过类似的示例,但我会尝试解释它是如何工作的。
type ValueRepresents = {
[K in ValueTypes]: Partial<Record<Exclude<ValueTypes, K>, false>> & Record<K, true>
}
创建的类型等效于:
type ValueRepresents = {
boolean: {
boolean: true;
number?: false;
other?: false;
};
number: {
boolean?: false;
number: true;
other?: false;
};
other: {
boolean?: false;
number?: true;
other: true;
};
};
并通过在方括号 [ValueTypes]
中添加联合类型,它提取了另一个联合类型中的那些(所有)键的值,等同于:
type ValueRepresents =
| {
boolean: true;
number?: false;
other?: false;
}
| {
boolean?: false;
number: true;
other?: false;
}
| {
boolean?: false;
number?: true;
other: true;
};