Typescript泛型、约束和文字类型
我有以下通用功能:Typescript泛型、约束和文字类型,typescript,typescript-generics,Typescript,Typescript Generics,我有以下通用功能: type Identity = <T extends string | number>(arg: T) => T; const identity: Identity = (x) => x; 我希望从identity返回的类型可以是字符串或数字,但是我似乎正在从'a'和1返回文本类型。为什么会这样?有没有办法改变我的约束,这就是我的行为 我已经找到了一些解决办法。首先,要首先将参数指定给变量,请执行以下操作: let a_param = 'a' let
type Identity = <T extends string | number>(arg: T) => T;
const identity: Identity = (x) => x;
我希望从identity
返回的类型可以是字符串
或数字
,但是我似乎正在从'a'
和1
返回文本类型。为什么会这样?有没有办法改变我的约束,这就是我的行为
我已经找到了一些解决办法。首先,要首先将参数指定给变量,请执行以下操作:
let a_param = 'a'
let a = identity(a_param);
a = 'b'; // Yay
let b_param = 1;
let b = identity(b_param);
b = 2; // Yay
第二,转换为字符串
或数字
:
let a = identity('a' as string);
a = 'b'; // Yay
let b = identity(1 as number);
b = 2; // Yay
这两种感觉都不对。我还在学习TS,所以我想我错过了一些东西。类型参数通常会被推断为与参数一致的最具体的可能类型;在本例中,字符串文本类型
'a'
。这几乎总是人们想要的行为
在您的例子中,推断类型过于严格,因为您将其用作变量的推断类型,而不仅仅是表达式的推断类型。因此,自然的解决方案是指定较弱的类型参数,如下所示:
let a = identity<string>('a');
您使用的是泛型,但您的需求与泛型相反。这是因为
identity('a')
实际上意味着identity('a')
,因此返回类型是'a'
(不是任何字符串)
(出于某种原因)有效的方法是:
我认为这是如何工作的,当您调用实现该类型的函数时,它解决了类型Identity
中哪些重载最匹配
let a = identity<string>('a');
let a: string = identity('a');
type Identity = {
(arg: number): number;
(arg: string): string;
}
const identity: Identity = (x: any) => x;
let a = identity('a');
a = 'b'; // yes
a = 3; // no
let b = identity(1);
b = 'b'; // no
b = 3; // yes