条件类型错误地推断联合类型

问题描述 投票:0回答:1

我正在尝试编写一个函数,该函数有条件地推断作为联合的通用输入参数的类型。当我将输入类型设置为条件时,它会抛出一个错误,表明它推断输入必须是联合中每个值的数组,而不是联合中任何值的数组。如果没有条件类型,它可以正确推断输入可以是联合中任何值的数组:

type StringUnion = 'a' | 'b' | 'c'

const a: StringUnion[] = ['a']
console.log(a)

function basicTest<T>(props: { data: T[] }): T {
  return props.data[0];
}
const basicResult = basicTest({ data: a }) // No error

function extendsTest<T extends string>(props: { data: T[] }): T {
  return props.data[0];
}
const extendsResult = extendsTest({ data: a }) // No error

function ternaryTest<T>(props: { data: T extends string ? T[] : { inner: T[] } }): T {
  if ('inner' in props.data) {
    return props.data.inner[0];
  }
  return props.data[0];
}
const ternaryResult = ternaryTest({ data: a }) // Error
// Type 'StringUnion[]' is not assignable to type '"a"[] | "b"[] | "c"[]'.
//   Type 'StringUnion[]' is not assignable to type '"a"[]'.
//     Type 'StringUnion' is not assignable to type '"a"'.
//       Type '"b"' is not assignable to type '"a"'.ts(2322)
//
// test.ts(16, 34): The expected type comes from property 'data' which is declared here on type '{ data: "a"[] | "b"[] | "c"[]; }'

使用条件类型时如何避免这种类型错误?

typescript generics types typescript-generics
1个回答
0
投票

问题在于联合类型的元素正在被映射(我认为这不是一个正确的术语)来推断类型参数,给你

"a"[] | "b"[] | "c"[]
而不是
StringUnion[]

您可以通过将

[]
放在
T
string
周围来防止这种情况发生:

function ternaryTest<T>(props: { data: [T] extends [string] ? T[] : { inner: T[] } }): T {
// −−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−^^^−−−−−−−−−^^^^^^^^
  if ('inner' in props.data) {
    return props.data.inner[0];
  }
  return props.data[0];
}

游乐场链接

© www.soinside.com 2019 - 2024. All rights reserved.