为什么typescript编译器不推断泛型参数?

为什么typescript编译器不推断泛型参数?,typescript,Typescript,我有这个密码 type Check<F, T> = F extends string ? string : T type Func2 = <F extends T[] | string, T>(functor: F) => Check<F, T> const x: Func2 = (x: any) => x[0] const y = x([1, 2]) const z = x("abc") 为什么T有unknow

我有这个密码

type Check<F, T> = F extends string
  ? string
  : T

type Func2 = <F extends T[] | string, T>(functor: F) => Check<F, T>

const x: Func2 = (x: any) => x[0]

const y = x([1, 2])
const z = x("abc")
为什么
T
unknown
,但是
T[]
的推断是正确的

为什么会发生这种情况

TS中的类型推断并不像您预期的那样工作。类型变量可以通过三种方式推断:

  • 基于已传递函数的参数
  • 基于函数返回值的分析
  • 基于先前推断的类型变量(此规则仅从左到右顺序应用)
这就是为什么您得到了
unknown
类型


您的解决方案可以是:

type Check<F, T> = F extends (infer U)[]
  ? U
  : T

type Func2 = <F extends any[] | string>(functor: F) => Check<F, string>

const x: Func2 = (x: any) => x[0]

const y = x([1, 2])
const z = x("abc")
类型检查=F扩展(推断U)[]
? U
:T
类型Func2=(functor:F)=>检查
常数x:Func2=(x:any)=>x[0]
常数y=x([1,2])
常数z=x(“abc”)
为什么会发生这种情况

TS中的类型推断并不像您预期的那样工作。类型变量可以通过三种方式推断:

  • 基于已传递函数的参数
  • 基于函数返回值的分析
  • 基于先前推断的类型变量(此规则仅从左到右顺序应用)
这就是为什么您得到了
unknown
类型


您的解决方案可以是:

type Check<F, T> = F extends (infer U)[]
  ? U
  : T

type Func2 = <F extends any[] | string>(functor: F) => Check<F, string>

const x: Func2 = (x: any) => x[0]

const y = x([1, 2])
const z = x("abc")
类型检查=F扩展(推断U)[]
? U
:T
类型Func2=(functor:F)=>检查
常数x:Func2=(x:any)=>x[0]
常数y=x([1,2])
常数z=x(“abc”)

x
的签名中没有
T
的推断位置
F
可以通过
functor
的类型来推断,但是您传入的任何内容都不会修复
T
,因此它会返回到
未知
。因此
F
仅限于
unknown[]| string
。我不知道为什么您更喜欢
Func2
的定义,而不是
type Func2=(functor:F)=>F[0]
。你能解释一下你想做什么以及为什么要这样做吗?@jcalz实际的代码也包含其他类型。检查实际代码。
x
的签名中没有
T
的推断位置
F
可以通过
functor
的类型来推断,但是您传入的任何内容都不会修复
T
,因此它会返回到
未知
。因此
F
仅限于
unknown[]| string
。我不知道为什么您更喜欢
Func2
的定义,而不是
type Func2=(functor:F)=>F[0]
。你能解释一下你想做什么以及为什么要这样做吗?@jcalz实际的代码也包含其他类型。检查实际代码。谢谢你@ааааааааааааааа。但是推断出的签名是正确的
const x:(functor:number[])=>unknown
。请检查一下是的,这是我的错,你是对的!答案已更新。谢谢你@аааааааааааааа1072。但是推断出的签名是正确的
const x:(functor:number[])=>unknown
。请检查一下是的,这是我的错,你是对的!答案已更新。