- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试编写通用“groupBy”函数的 typescript 签名,该函数会将已区分类型的联合数组“传播”到记录中,其中记录的每个字段都是一个可能的鉴别器值并指向一个对象数组来自联合的具体类型。
例子:
interface Dog {
type: 'dog'
dogMetadata: {}
}
interface Cat {
type: 'cat'
catMetadata: {}
}
type Animal = Dog | Cat
const animals: Animal[] = [{ type: 'dog', dogMetadata: {} }, { type: 'cat', catMetadata: {} }]
每个接口(interface)都有一个共同的鉴别器属性,没有其他共同的属性。
这是一个简单的“groupBy”签名,它不传播类型联合值,迫使我向下转换记录的值:
function groupBy<T, K extends string>(arr: T[], keyExtractor: (element: T) => K): Record<K, T[]>
const animalsByType: Record<'dog' | 'cat', Animal[]> = groupBy(animals, it => it.type)
const dogs: Dog[] = animalsByType['dog'] as Dog[] // Must downcast Animal[] to Dog[]
我怎样才能创建一个“groupBy”来识别被区分的联合类型的具体类型?我想要这样的东西:
const animalsByType: { dog: Dog[], cat: Cat[] } = groupBy(animals, it => it.type)
const dogs: Dog[] = animalsByType['dog'] // animalsByType.dog is known to be Dog[] by typescript
实现很简单,Typescript 部分有问题 :) 我正在寻找一个不做假设的通用解决方案,例如鉴别器属性的名称或类型联合中的类型数量。
跟进问题
当联合嵌套在另一个类中时,是否可以使相同的签名起作用?
interface Holder<T> {
data: T
}
const animalHolders: Holder<Animal>[] = animals.map(data => ({ data }))
const dogHolders: Holder<Dog> = groupBy(animalHolders, it => it.data.type) // Any way of doing this?
感谢您的帮助。
最佳答案
好问题...
让我们首先创建一些实用程序类型:
type KeysOfType<O, T> = {
[K in keyof O]: O[K] extends T ? K : never;
}[keyof O];
这会提取 O
的所有键指向 T
类型的值.这将用于将判别式的类型限制为属于 string
的类型。类型。它们将在您的输出类型中用作键,因此我们对允许其他类型的判别式并不真正感兴趣。
我们还要添加 Expand<T>
使我们的结果类型在智能感知中看起来更好。
type Expand<T> = T extends infer O ? { [K in keyof O]: O[K] } : never;
现在,让我们创建一个类型来表示您的 groupBy
的返回类型功能:
type Return<T, K extends KeysOfType<T, string>> =
{ [KK in string & T[K]]: { [_ in K]: KK } & T }
或者,可选地,自由地应用 Expand<T>
为消费者输入更好的智能感知:
type Return<T, K extends KeysOfType<T, string>> =
Expand<{ [KK in string & T[K]]: Expand<{ [_ in K]: KK } & T> }>
现在我们可以声明函数了:
function groupBy<T, K extends KeysOfType<T, string>>(
arr: T[],
keyExtractor: (element: T) => T[K]): Return<T, K>{
throw Error();
}
并调用它:
const groups = groupBy(animals, e => e.type)
为了完全类型安全,无论选择哪个鉴别器属性。
关于Typescript 通过鉴别器属性将已鉴别联合类型的数组分组到记录中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71602319/
我写了一段代码,在比特流中连续 6 个“1”后添加一个“0”。但是如何解码呢? 这里是一个比特流的例子: original = {01101111110111000101111110001100...
我是一名优秀的程序员,十分优秀!