duc*_*cin 3 generics type-systems typescript
以下泛型类型有什么区别:
type FnWithRequiredParam<T> = (t: T) => void
type FnWithParamInferred = <T>(t: T) => void
Run Code Online (Sandbox Code Playgroud)
据我所知,如果没有在任何上下文中明确给出泛型类型,FnWithRequiredParam则总是会失败.传递泛型(强制执行),例如,基本上将它转换为所有上下文.FnWithRequiredParam<string>(t: string) => void
但是,我找不到的意思了FnWithParamInferred.在某些上下文中<T>,从它使用的位置(例如Array.map)推断,但是以下行会引发错误:
var f: FnWithParamInferred = (a: number) => { console.log(a) }
Run Code Online (Sandbox Code Playgroud)
说number与T不兼容.在上面这行,究竟是T什么?它从未被精确地声明,并且正在与另一种类型进行比较.确定T函数类型中定义的泛型是什么规则是什么<T>(...) => ...?
似乎,如果<T>被定义为类/接口的必需泛型,例如Array<T>,那么方法od数组可以成功地推断出来T.但是如果它在类/接口之外,类型推断似乎不起作用.
Tit*_*mir 10
这两者在他们定义的功能签名上非常不同.
T,与T被推断(或显式地指定)时调用该函数.请考虑以下声明:
declare const fn: FnWithRequiredParam<number>
declare const genericFn: FnWithParamInferred;
// T was fixed on declaration
fn(1) // ok
fn("1") // err
// T is decded by the caller
genericFn(1) // ok T is number for this call
genericFn("1") // ok T is string for this call
genericFn<number>("1") // err T was specified as number but string was passed in
Run Code Online (Sandbox Code Playgroud)
之所以你所得到的错误是,你正试图分配功能与number参数应该接受任何类型的参数的功能T,与T由函数的调用者来决定.只有通用函数才能满足该类型FnWithParamInferred
var f: FnWithParamInferred = <T>(a: T) => { console.log(a) }
Run Code Online (Sandbox Code Playgroud)
我认为你真正想要的是能够从变量声明中省略显式类型参数,并根据分配给它的值来推断它.Typescript不支持这个.如果为变量定义类型注释,则不会对变量进行推理.
您可以完全省略类型注释,让编译器推断出函数类型:
var f = (a: number) => { console.log(a) } // inferred as (a: number) => void
Run Code Online (Sandbox Code Playgroud)
或者您可以定义一个通用的辅助函数来推断T,但是可以根据它来限制函数签名FnWithRequiredParam
function createFunction<T>(fn: FnWithRequiredParam<T>) {
return fn;
}
var f = createFunction((a: number) => { console.log(a) }) // inferred as FnWithRequiredParam<number>
Run Code Online (Sandbox Code Playgroud)