要返回的映射'(换行<A>|换行<B>)[]"而不是"换行<A|B>[]"

  • 本文关键字:换行 返回 映射 typescript
  • 更新时间 :
  • 英文 :


我正在尝试解决代码:

type Wrap<T> = {
value: T
}
function wrapIt<T>(t: T): Wrap<T> {
return { value: t}
}
const arr: Array<string|number> = ["a", 1]
const arr2: Array<Wrap<string|number>> = arr.map(wrapIt)
const arr3: Array<Wrap<string>|Wrap<number>> = arr.map(wrapIt) // <--- Doesn't compile

编译器说:

Type 'Wrap<string | number>[]' is not assignable to type '(Wrap<string> | Wrap<number>)[]'.
Type 'Wrap<string | number>' is not assignable to type 'Wrap<string> | Wrap<number>'.
Type 'Wrap<string | number>' is not assignable to type 'Wrap<string>'.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.

arr3是我与其他一些我不拥有的代码兼容所需要的。此外,从概念上讲,它似乎更正确。

有没有一些打字黑魔法可以让它按照我想要的方式运行?现在,我将使用as键入强制转换。

编辑:Array<string|number>只是一个例子,我经常使用这种模式,所以我希望解决方案适用于Array<T>,其中T是任意的,可以是像string|number一样的并集,但不仅仅是。

您可以在返回类型时更改函数的定义,使其分布在T上。因此,这意味着当映射并集(如number | string(时,您将为每个并集组成部分(因此为Wrapped<number> | Wrapped<string>(获得Wrapped的实例化的并集,而不是为并集(因此不是Wrapped<string | number>(获得Wrapped的实例化

type DistraibutiveWrapped<T> = T extends T ? Wrap<T> : never
function wrapIt<T>(t: T): DistraibutiveWrapped<T> {
return { value: t} as DistraibutiveWrapped<T>
}

游乐场链接

是否使用显式类型检查?

type Wrap<T> = {
value: T
}
function wrapIt<T>(t: T): Wrap<T> {
return { value: t }
}
const arr: Array<string | number> = ["a", 1]
const arr2: Array<Wrap<string | number>> = arr.map(wrapIt)
const arr3: Array<Wrap<string> | Wrap<number>> = arr.map(x => {
switch (typeof x) {
case 'string':
return wrapIt<string>(x);
case 'number':
return wrapIt<number>(x);
default:
return wrapIt(x);
}
});

您可以创建额外的函数并重载它:

type Wrap<T> = {
value: T
}
function wrapIt<T>(t: T): Wrap<T> {
return { value: t }
}
const arr: Array<string | number> = ["a", 1]
function map<Item,>(arr: Item[]): Array<Wrap<string> | Wrap<number>>
function map<Item,>(arr: Item[]) {
return arr.map(wrapIt)
}
// (Wrap<string> | Wrap<number>)[] which is equivalent to Array<Wrap<string> | Wrap<number>>, just different syntax
const result = map(['hello', 42])

游乐场

最新更新