Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TypeScript中的参数类型推断_Typescript - Fatal编程技术网

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:从不

我们可以将其视为“get
T
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