类型不可分配给类型 2322
Type is not assignable to type 2322
为什么会引发以下问题:Type '(...args: T) => void' is not assignable to type 'Fn<T>'.(2322)
:
type Fn<T extends unknown[]|unknown> = T extends unknown[] ? (...args: T)=>void : T
const func = <T extends unknown[]>()=>{
// why does this error and how does one resolve it?
// ideal Fn must handle cases outside of unknown[] including `any` and `unknown`
const fn : Fn<T> = (...args: T)=> console.log(args)
return fn
}
// some tests by me to try and understand what is going on:
type ValidFn1 = Fn<[value:number]>
type ValidFn2 = Fn<any>
type ValidFn3 = Fn<never>
type ValidFn4 = Fn<unknown>
type ValidFn5 = Fn<unknown[]>
type ValidFn6 = Fn<void>
const validFn1: ValidFn1 = (...args)=>console.log(args) // extends unknown[]
const validFn2: ValidFn2 = (...args:any)=>console.log(args) // any extends unknown[]
const validFn3: ValidFn3 = (...args:never)=>console.log(args) // never doesn't extend unknown[]
const validFn4: ValidFn4 = (...args:unknown)=>console.log(args) // unknown doesn't extend unknown[]
const validFn5: ValidFn5 = (...args:unknown[])=>console.log(args) // extends unknown[]
const validFn6: ValidFn6 = (...args:void)=>console.log(args) // void doesn't extend unknown[]
我相信这里发生的事情是以下事实的结合:(1) Typescript 在提供具体实例化之前不会解析函数内部的条件类型(请参阅 ) and (2) function parameters are contravariant (see )。
所以,你在这里看到的基本上是 TS 看到这一行:
const fn : Fn<T> = (...args: T)=> console.log(args)
并且:
将 func
中的 Fn<T>
解析为 Fn<unknown[]>
,即 (...args: unknown[]) => void
,(因为上面的第 1 点)
意识到右侧的 T
可能比 unknown[]
更窄(例如,number[]
)。
然后它认为,嗯,这可能行不通,因为,这可能是说,例如:
const fn:(args:unknown[])=>void = (args:number[])=>console.log(args)
这是一个错误,因为 args 是逆变的(参见上面的第 2 点)。
你是怎么解决的?我认为解决第 1 点类别下问题的最简单方法是在函数上使用显式 return 类型,然后仅在函数本身内部进行断言,例如:
const func = <T extends unknown[]>():Fn<T>=>{
const fn = (...args: T)=> console.log(args)
return fn as Fn<T>
}
为什么会引发以下问题:Type '(...args: T) => void' is not assignable to type 'Fn<T>'.(2322)
:
type Fn<T extends unknown[]|unknown> = T extends unknown[] ? (...args: T)=>void : T
const func = <T extends unknown[]>()=>{
// why does this error and how does one resolve it?
// ideal Fn must handle cases outside of unknown[] including `any` and `unknown`
const fn : Fn<T> = (...args: T)=> console.log(args)
return fn
}
// some tests by me to try and understand what is going on:
type ValidFn1 = Fn<[value:number]>
type ValidFn2 = Fn<any>
type ValidFn3 = Fn<never>
type ValidFn4 = Fn<unknown>
type ValidFn5 = Fn<unknown[]>
type ValidFn6 = Fn<void>
const validFn1: ValidFn1 = (...args)=>console.log(args) // extends unknown[]
const validFn2: ValidFn2 = (...args:any)=>console.log(args) // any extends unknown[]
const validFn3: ValidFn3 = (...args:never)=>console.log(args) // never doesn't extend unknown[]
const validFn4: ValidFn4 = (...args:unknown)=>console.log(args) // unknown doesn't extend unknown[]
const validFn5: ValidFn5 = (...args:unknown[])=>console.log(args) // extends unknown[]
const validFn6: ValidFn6 = (...args:void)=>console.log(args) // void doesn't extend unknown[]
我相信这里发生的事情是以下事实的结合:(1) Typescript 在提供具体实例化之前不会解析函数内部的条件类型(请参阅
所以,你在这里看到的基本上是 TS 看到这一行:
const fn : Fn<T> = (...args: T)=> console.log(args)
并且:
将
func
中的Fn<T>
解析为Fn<unknown[]>
,即(...args: unknown[]) => void
,(因为上面的第 1 点)意识到右侧的
T
可能比unknown[]
更窄(例如,number[]
)。
然后它认为,嗯,这可能行不通,因为,这可能是说,例如:
const fn:(args:unknown[])=>void = (args:number[])=>console.log(args)
这是一个错误,因为 args 是逆变的(参见上面的第 2 点)。
你是怎么解决的?我认为解决第 1 点类别下问题的最简单方法是在函数上使用显式 return 类型,然后仅在函数本身内部进行断言,例如:
const func = <T extends unknown[]>():Fn<T>=>{
const fn = (...args: T)=> console.log(args)
return fn as Fn<T>
}