打字稿将字符串联合类型转换为另一种类型的交集

时间:2021-07-09 09:40:03

标签: typescript

我有以下联合类型:

type Foo = 'ol' | 'ul';

我想以某种方式使用泛型将其转换为这个(因为 Foo 可能会更改为包含其他)

type Bar = OtherType<'ol'> & OtherType<'ul'>;

我不太确定从哪里开始...

编辑:React 的一个更具体的例子是:

type Elements = 'ol' | 'ul';

// ... somehow transform to:

type Props = JSX.IntrinsicElements['ol'] & JSX.IntrinsicElements['ul']

2 个答案:

答案 0 :(得分:0)

import React from 'react'


// credits goes to https://stackoverflow.com/a/50375286
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
  k: infer I
) => void
  ? I
  : never;

type OtherType<T extends keyof JSX.IntrinsicElements> = UnionToIntersection<JSX.IntrinsicElements[T]>

type Result = OtherType<'ol' | 'ul'>;

declare var x: Result
declare var y: JSX.IntrinsicElements['ol'] & JSX.IntrinsicElements['ul']

x = y // ok

y = x // ok

Playground

Union Distribution 将为您完成工作

答案 1 :(得分:0)

OtherType 可能不会分布在联合上时,这里有一个通常有效的解决方案:它利用函数参数类型的逆变将联合转换为交集。

type MakeIntersection<T> = (T extends infer U ? (x: OtherType<U>) => void : never) extends (x: infer V) => void ? V : never

Playground Link