TypeScript中的参数类型推断
我有以下代码:TypeScript中的参数类型推断,typescript,Typescript,我有以下代码: type Inferred<T> = T extends (...args: (infer UnionType)[]) => any ? UnionType : never function f(first: 'first', second: 'second', bool: boolean) {} type T = Inferred<typeof f> // never 或相当于: type Inferred<T> = T exte
type Inferred<T> = T extends (...args: (infer UnionType)[]) => any ? UnionType : never
function f(first: 'first', second: 'second', bool: boolean) {}
type T = Inferred<typeof f> // never
或相当于:
type Inferred<T> = T extends (...args: infer A) => any ? A[number] : never
function f(first: 'first', second: 'second', bool: boolean) {}
type T = Inferred<typeof f> // union type
type推断=T扩展(…args:infera)=>any?A[数字]:从不
函数f(第一:“第一”,第二:“第二”,布尔值:{}
类型T=推断//联合类型
为什么第一种方法不起作用?这是因为有限参数的函数不能扩展(可能)无限参数的函数:
//X为false
X型=
((a:string,b:number)=>any)扩展((…args:(string | number)[])=>any)
? 真的
:假;
您的第二个和第二个方法都使用元组类型(
['first','second',boolean]
),它有一个已知的有限长度,允许它们工作。要回答这个问题,让我们退一步,从更广泛的角度来看
TypeScript对元组和数组使用相同的语法(即[]
)。但它们是截然不同的概念。在下面的段落中,为了简洁起见,我将使用()
(而不是标准TypeScript的[]
)作为元组。另外,请记住TypeScript中的T[]==Array
元组按惯例是固定长度和异构的(包含可能不同类型的值)(1,“Adam”,42)
是类型为(数字、字符串、数字)
的元组
数组通常是同质的(保存相同类型的值)和任意长度的
在TypeScript中,由于联合类型的支持,二者之间的区别略微模糊,即[1,“Adam”,42]
在T=number | string
时也是一个完美的数组。这在没有联合类型支持的语言中是不可能的(这将导致找到number | string
的最低上限,通常类似于any
)
在提供的示例中使用此知识
type推断=T扩展(…参数:(推断联合类型)[])=>any?UnionType:从不
我们可以将其视为“getT
out of function with arguments”类型的列表Array
我们知道,参数类型的列表包括:
函数f(第一个:“第一”,第二个:“第二”,布尔值:布尔值)
是('first','second',boolean)
此时,需要实现以下统一(:=:
):
('first','second',boolean):=:Array
因此,无论在哪里使用('first','second',boolean)
类型的值,都可以使用数组类型的值。实际上没有这样的T,因此推断的从不
这可能看起来像是T=string | boolean
甚至T='first'|'second'| boolean
在这里是一个解决方案,但是:
type Arr = Array<'first' | 'second' | boolean>
type Tuple = ['first', 'second', boolean]
const a: Arr = ['first', 'second', true]
const t: Tuple = ['first', 'second', true]
let a1: Arr = t;
let t1: Tuple = a; // Type error no. 2322
或在类型级别:
type TEA = Tuple extends Arr ? true : false // true
type AET = Arr extends Tuple ? true : false // false
它还解释了为什么typey=expertedvoid>
产生number
总而言之,示例中的(推断UnionType)[
似乎不支持推断元组类型,只支持数组
免责声明-我不熟悉TypeScript编译器的内部结构,这是我根据一般知识和直觉来解释这里发生的事情的最好尝试。这听起来很有说服力,但在TypeScript 4.1.2中似乎并不适用
Target requires 3 element(s) but source may have fewer.(2322)
type TEA = Tuple extends Arr ? true : false // true
type AET = Arr extends Tuple ? true : false // false