在 TypeScript 中获取数组子集的类型
Getting the Type of a Subset of an Array in TypeScript
我有一个数据结构(它可以是一个数组或一个对象)来保存一些设置数据。目前看起来像这样:
const settings = [
{name: 'Albert', value: 'a', isDefault: true},
{name: 'Bradley', value: 'b'}
] as const
以及
的类型
type TAllValues = settings[number]['value'] // is 'a' | 'b' <-- that Union Type is what I want
我希望做的是能够根据设置中的匹配条件过滤此列表以获得子集。像这样
type TDefaultValues = FilterSettings<settings, {isDefault: true}> // would be just 'a'
我可以传入具有此形状的 type
和 condition
并为符合条件的条目获取值的联合类型。
如果有帮助,我也可以将数据结构更改为对象:
const settings = {
a: {name: 'Albert', isDefault: true},
b: {name: 'Bradley'}
}
编辑
注意 - WebStorm 存在一个问题,它以不同方式对待某些联合。我还没有发现为什么会这样,但是 Barkers
和 Barkers2
在我尝试过的所有其他环境中都是一样的。在 Webstorm 中,从“as const”对对象的子集使用扩展是错误的,在其他任何地方都是正确的。
const Animals = [
{ animal: 'cat', bark: false },
{ animal: 'dog', bark: true }
] as const
type TAnimals = typeof Animals[number]
type TAnimals2 = { animal: 'cat'; bark: false } | { animal: 'dog'; bark: true }
type Barkers = Extract<TAnimals, { bark: true }> // <--- never
type Barkers2 = Extract<TAnimals2, { bark: true }> // <--- correct
您可以使用 distributive conditional type 检查设置是否符合条件,select 仅检查符合条件的设置:
const settings = [
{ name: 'Albert', value: 'a', isDefault: true },
{ name: 'Bradley', value: 'b' }
] as const
type Setting = typeof settings[number]
type FilterSettings<Condition, S extends Setting = Setting> =
S extends Condition ? S["value"] : never
type TDefaultValues = FilterSettings<{ isDefault: true }> // "a"
我有一个数据结构(它可以是一个数组或一个对象)来保存一些设置数据。目前看起来像这样:
const settings = [
{name: 'Albert', value: 'a', isDefault: true},
{name: 'Bradley', value: 'b'}
] as const
以及
的类型type TAllValues = settings[number]['value'] // is 'a' | 'b' <-- that Union Type is what I want
我希望做的是能够根据设置中的匹配条件过滤此列表以获得子集。像这样
type TDefaultValues = FilterSettings<settings, {isDefault: true}> // would be just 'a'
我可以传入具有此形状的 type
和 condition
并为符合条件的条目获取值的联合类型。
如果有帮助,我也可以将数据结构更改为对象:
const settings = {
a: {name: 'Albert', isDefault: true},
b: {name: 'Bradley'}
}
编辑
注意 - WebStorm 存在一个问题,它以不同方式对待某些联合。我还没有发现为什么会这样,但是 Barkers
和 Barkers2
在我尝试过的所有其他环境中都是一样的。在 Webstorm 中,从“as const”对对象的子集使用扩展是错误的,在其他任何地方都是正确的。
const Animals = [
{ animal: 'cat', bark: false },
{ animal: 'dog', bark: true }
] as const
type TAnimals = typeof Animals[number]
type TAnimals2 = { animal: 'cat'; bark: false } | { animal: 'dog'; bark: true }
type Barkers = Extract<TAnimals, { bark: true }> // <--- never
type Barkers2 = Extract<TAnimals2, { bark: true }> // <--- correct
您可以使用 distributive conditional type 检查设置是否符合条件,select 仅检查符合条件的设置:
const settings = [
{ name: 'Albert', value: 'a', isDefault: true },
{ name: 'Bradley', value: 'b' }
] as const
type Setting = typeof settings[number]
type FilterSettings<Condition, S extends Setting = Setting> =
S extends Condition ? S["value"] : never
type TDefaultValues = FilterSettings<{ isDefault: true }> // "a"