ChatGPT解决这个技术问题 Extra ChatGPT

带有泛型的 Typescript 箭头函数的语法是什么?

打字稿手册目前没有关于箭头功能的内容。普通函数可以使用以下语法进行一般类型化:示例:

function identity<T>(arg: T): T {
    return arg;
}

箭头函数的语法是什么?


j
jbmilgrom

编辑

根据@Thomas 的评论,在较新的 TS 编译器中,我们可以简单地执行以下操作:

const foo = <T,>(x: T) => x;

原始答案

解释语法 referenced by Robin... 的完整示例将它带回家:

通用函数

像下面这样的东西可以正常工作:

function foo<T>(x: T): T { return x; }

但是,使用箭头泛型函数不会:

const foo = <T>(x: T) => x; // ERROR : unclosed `T` tag

解决方法:在泛型参数上使用 extends 来提示编译器它是泛型的,例如:

const foo = <T extends unknown>(x: T) => x;

是否可以为 const foo 声明一些预定义的泛型类型?即 type GenericFun<T, A=T> = (payload: A) => T; 然后使 const foo: GenericFun 仍然通用而不提供 T 类型?
您的第二个示例只是 .tsx 文件(TypeScript + JSX)中的错误。正如您在 TypeScript playground 中看到的那样,在 .ts 文件中它工作正常。
较新的 typescript 编译器还支持尾随逗号 const foo = <T,>(x: T) => x; 以避开 JSX 歧义。
@danvk 值得注意的是,这仅适用于那些在 TS 文件中禁止 JSX 的人 - 如果项目配置为允许 TS 文件中的 JSX,您仍然需要“扩展”或尾随逗号
这就是要点:“使用 .ts 而不是 .tsx 扩展名”?
m
mb21

如果您在 .tsx 文件中,则不能只写 <T>,但这有效:

const foo = <T, >(x: T) => x;

extends {} hack 不同,此 hack 至少保留了意图。


他们是否打算修复这种行为?
我想对此无能为力...... JSX 和 Typescript 通用语法在这里发生冲突......
太棒了 - 这是迄今为止最好的答案:完美运行并且根本不会改变行为!
默认类型参数类型呢? const foo = <T = any,>(x: T) => x 不起作用...
为什么这个黑客有效?在这种情况下,逗号是什么意思?
k
k0pernikus

我发现上面的例子令人困惑。我正在使用 React 和 JSX,所以我认为它使场景复杂化。

我从 TypeScript Deep Dive 得到了澄清,其中指出了箭头泛型:

解决方法:在泛型参数上使用 extends 来提示编译器它是泛型的,这来自一个对我有帮助的更简单的示例。

    const identity = < T extends {} >(arg: T): T => { return arg; }

“T extends any”将支持 void。
虽然它工作得很好,但我必须说它看起来确实有点像黑客......
H
Harshit Singhai

这对我有用

const Generic = <T> (value: T) => {
    return value;
} 

如果在 .ts 文件中这有效。否则必须延长。
这在 vscode 中的 .ts 和 .tsx 文件中对我来说很好用
A
Andreas Frische

语言规范在 p.64f 上说

< T > ( ... ) => { ... } 形式的构造可以被解析为带有类型参数的箭头函数表达式或应用于没有类型参数的箭头函数的类型断言。它被解决为前者[..]

例子:

// helper function needed because Backbone-couchdb's sync does not return a jqxhr
let fetched = <
           R extends Backbone.Collection<any> >(c:R) => {
               return new Promise(function (fulfill, reject) {
                   c.fetch({reset: true, success: fulfill, error: reject})
               });
           };

你的例子太复杂了,这就是为什么来自 Harshit Singhai 的类似例子获得更多选票
B
Bear

这么晚了,但是有了 ES6 就不需要扩展它仍然对我有用.... :)

let getArray = <T>(items: T[]): T[] => {
    return new Array<T>().concat(items)
}

let myNumArr = getArray<number>([100, 200, 300]);
let myStrArr = getArray<string>(["Hello", "World"]);
myNumArr.push(1)
console.log(myNumArr)

这对我不起作用,我必须像这样添加一个逗号:<T, >。如@jbmilgrom 回答下的@Thomas 评论中所述
您应该在发布之前阅读其他解决方案。您的解决方案已经发布并附有解释。它仅适用于 .ts 文件,而不是 .tsx 文件。
不起作用,因为没有逗号。 VSCode 捕获的语法错误
c
const.takeo

这对我有用

 const logSomething = <T>(something:T): T => {
       return something;
    }

但这已经被建议很多次了
M
Michal Filip

虽然 extends {} 的流行答案有效并且比 extends any 更好,但它强制 T 成为一个对象

const foo = <T extends {}>(x: T) => x;

为避免这种情况并保持类型安全,您可以改用 extends unknown

const foo = <T extends unknown>(x: T) => x;

R
Roy Art

我使用这种类型的声明:

const identity: { <T>(arg: T): T } = (arg) => arg;

如果您需要,它允许为您的函数定义额外的道具,并且在某些情况下,它有助于使函数体从通用定义中保持清洁。

如果您不需要额外的道具(命名空间之类的东西),它可以简化为:

const identity: <T>(arg: T) => T = (arg) => arg;

在函数体内使用 <T> 时,这对我不起作用。 Typescript 告诉我 <T> 没有用于函数定义位置的 <T>,并告诉我它在函数体中我引用它的位置找不到 <T>。使用 <T,> 'hack' 我没有这个问题。
L
LearnToLive

我知道我迟到了这个答案。但是想回答这个问题,以防其他人觉得它有帮助。没有一个答案提到如何将泛型与 async 箭头函数一起使用。

就这样:

const example = async <T> (value: T) => {
    //awaiting for some Promise to resolve or reject;
     const result = await randomApi.getData(value);

} 

C
CodeFarmer

2021 年,Ts 4.3.3

const useRequest = <DataType, ErrorType>(url: string): Response<DataType, ErrorType> 
   => {
      ...
   }

如果需要,请移动 => 1 行以上
E
Ester Kaufman

为多个依赖的泛型类型添加示例:

此函数已转换为箭头函数,如下所示:

http.get = function <T = any, R = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R> {
            config.withCredentials = true;
            ....
          };

注意扩展而不是等号:

http.get = async <T extends any, R extends unknown = AxiosResponse<T>>(url: string, config?: AxiosRequestConfig): Promise<R> => {
            config.withCredentials = true;
            ...
          };

N
Nkoro Joseph Ahamefula

https://i.stack.imgur.com/LuzEI.png

当您尝试将 null 作为参数传递时,使用 会引发错误。我更喜欢使用 因为它可以解决问题。我还没有得到原因。但这对我有用。

https://i.stack.imgur.com/cTthY.png


Y
Yuh Lee

在这里,我得到了 2 例带有泛型的箭头函数:

直接调用:

const foo = <T>(value: T): void => {
    console.log(value);
foo('hello') // hello
}

要创建稍后使用的类型:

type TFoo<S> = (value: S) => boolean;
const foo: TFoo<number> = (value) => value>0;
console.log(foo(1)) // true
console.log(foo(-1)) // false

希望这在某个地方有所帮助!