如何使用带有React的Typescript/JSX中的箭头函数的泛型?

Ste*_*n G 6 generics lambda typescript reactjs react-jsx

使用Typescript,在Visual Studio中键入".ts"文件,请考虑以下声明:

export const foo = <T>(myObject: T) => myObject.toString();
Run Code Online (Sandbox Code Playgroud)

这很好用,类型检查很好,一切都很棒.

现在将完全相同的代码放入用于JSX和React的".tsx"文件中.

Intellisense非常沮丧和抱怨,因为它试图将<T>变成React JSX元素.但我的目的是让编译器将其视为通用类型指示符.

编译器抱怨:

[gulp-typescript] 17008 JSX元素'T'没有对应的结束标记.

我已经尝试了许多语法解决方法来尝试让IDE和编译器让我逃脱J​​SX并强制编译器将<T>理解为通用,就像JSX未使用时一样.但我找不到这种魔法酱.

谁比我更聪明谁能想到这一点?

tok*_*and 30

一种解决方法是添加尾随逗号:

export const foo = <T,>(myObject: T) => myObject.toString();
Run Code Online (Sandbox Code Playgroud)


Dan*_*ser 6

当您有一个类型参数时,TypeScript不确定它是否可能是JSX开始标记.它必须选择一个,所以它与JSX一起使用.

如果您想要一个具有完全相同语义的函数,您可以明确列出以下约束T:

const foo = <T extends {}>(myObject: T) => myObject.toString();
Run Code Online (Sandbox Code Playgroud)

这打破了TypeScript的歧义,以便您可以使用泛型类型参数.它也具有相同的语义,因为类型参数始终具有隐式约束{}.

  • 不要使用这个。如今(TS 3.5 及更高版本)隐式约束是“未知”:https://devblogs.microsoft.com/typescript/announcing-typescript-3-5/#generic-type-parameters-are-implicitly-constrained-to-未知 (6认同)

Pet*_*bev 5

我个人使用extends unknown. 对我来说听起来最安全

const foo = <T extends unknown>(myObject: T) => myObject.toString();
Run Code Online (Sandbox Code Playgroud)