使用泛型的Typescript箭头函数的语法是什么?

And*_*che 116 typescript

打字稿手册目前在箭头功能上没有任何内容.可以使用以下语法对普通函数进行泛型输入:示例:

function identity<T>(arg: T): T {
    return arg;
}
Run Code Online (Sandbox Code Playgroud)

箭头函数的语法是什么?

jbm*_*rom 129

完整的例子解释了Robin引用的语法...让我回家:

通用功能

像下面这样的工作正常:

function foo<T>(x: T): T { return x; }
Run Code Online (Sandbox Code Playgroud)

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

const foo = <T>(x: T) => x; // ERROR : unclosed `T` tag
Run Code Online (Sandbox Code Playgroud)

解决方法:对泛型参数使用扩展来提示编译器它是通用的,例如:

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

  • 较新的打字稿编译器还支持逗号const foo = &lt;T,&gt;(x:T)=&gt; x;`来避免JSX的歧义。 (15认同)
  • 是否可以为 `const foo` 声明一些预定义的泛型类型?即`type GenericFun&lt;T, A=T&gt; = (payload: A) =&gt; T;` 然后让`const foo: GenericFun` 仍然是泛型而不提供`T` 类型? (7认同)
  • 如何设置默认泛型类型?`const foo = &lt;T = any,&gt;(x: T) =&gt; x` 不起作用,我总是得到 `unknown` (5认同)
  • @danvk 值得注意的是,这只适用于那些在 TS 文件中禁止 JSX 的人 - 如果项目配置为允许 TS 文件中的 JSX,您仍然需要“extends”或尾随逗号 (4认同)
  • 您的第二个示例只是`.tsx`文件(TypeScript + JSX)中的错误。在`.ts`文件中,它工作正常,如您在[TypeScript游乐场]上所见(http://www.typescriptlang.org/play/#src=const%20foo%20%3D%20%3CT%3E (x%3A%20T)%20%3D%3E%20x%3B%0D%0A)。 (3认同)
  • 根据 [TypeScript 文档](https://www.typescriptlang.org/docs/handbook/2/generics.html#generic-types),您可以创建一个通用箭头函数,如下所示: `const foo: &lt;T&gt; (x: T) =&gt; T = (x) =&gt; x` (3认同)
  • 那么这就是要点:“使用 .ts 而不是 .tsx 扩展名”吗? (2认同)
  • 如果您不打算使用任何 JSX,当然不要使用 .tsx。对我来说,它有助于区分具有某些组件的文件与具有某种功能的文件...... (2认同)

Rob*_*ten 45

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

我得到了澄清.https://basarat.gitbooks.io/typescript/content/docs/types/generics.html

箭头泛型的哪些状态:解决方法:使用扩展泛型参数来提示编译器它是通用的,这来自一个帮助我的简单示例.

    const identity = < T extends {} >(arg: T): T => { return arg; }
Run Code Online (Sandbox Code Playgroud)

  • "T延伸任何"将支持无效. (4认同)

And*_*che 29

语言规范在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})
               });
           };
Run Code Online (Sandbox Code Playgroud)


小智 22

这么晚了,但是使用 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)
Run Code Online (Sandbox Code Playgroud)

  • 这对我不起作用,我必须添加一个逗号,如下所示:`&lt;T,&gt;`。如 @jbmilgrom' 答案下的 @Thomas 评论中所述 (3认同)
  • 您应该在发布解决方案之前阅读其他解决方案。您的解决方案已经发布并附有解释。它仅适用于 .ts 文件,不适用于 .tsx 文件。 (2认同)

小智 22

这对我有用

 const logSomething = <T>(something:T): T => {
       return something;
    }
Run Code Online (Sandbox Code Playgroud)

  • 但这已经被建议过很多次了 (4认同)

mb2*_*b21 17

如果您在.tsx文件中,则不能只写<T>,但这可以工作:

const foo = <T, >(x: T) => x;
Run Code Online (Sandbox Code Playgroud)

extends {}hack 相对,此hack至少保留了意图。

  • 默认类型参数类型怎么样?`const foo = &lt;T = any,&gt;(x: T) =&gt; x` 不起作用... (8认同)
  • 为什么这个黑客有效?在这种情况下,逗号表示什么? (3认同)
  • 他们计划纠正这种行为吗? (2认同)
  • 太棒了 - 这是迄今为止最好的答案:完美地工作并且根本不会改变行为! (2认同)

Arc*_*ano 10

非箭头函数方式。扩展 OP 中的示例。

function foo<T>(abc: T): T {
    console.log(abc);
    return abc;
}

const x = { abc: 123 };
foo(x);

const y = 123;
foo<number>(y);
Run Code Online (Sandbox Code Playgroud)

除了将整个事情嵌入到一个声明中的答案之外:

const yar = <T,>(abc: T) => {
    console.log(abc);
    return abc;
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用中间类型:

type XX = <T>(abc: T) => T;

const bar: XX = (abc) => {
    console.log(abc);
    return abc;
}
Run Code Online (Sandbox Code Playgroud)

操场


小智 9

虽然流行的答案 withextends {}有效并且比 好extends any,但它迫使 theT成为一个对象

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

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

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


小智 8

这对我有用

const Generic = <T> (value: T) => {
    return value;
} 
Run Code Online (Sandbox Code Playgroud)

  • 如果在“.ts”文件中,则此方法有效。否则就必须延长。 (12认同)
  • JSX 元素 'T' 没有相应的结束标记。ts(17008) 找不到名称 'T'.ts(2304) 在 vs code 中的 tsx 文件中不起作用 (3认同)
  • 工作得很好:https://typescript-play.js.org/#code/DYUwLgBAzgFg9gVzIsAVAngBxBAvBAHlQD4AKANwENgEQAuCVASj2ImpACcxSADKmjjBYcASygQAJAG9h2OADMIA2gF9eTANwAobbBQoM2UgCJKlE0yA (2认同)

Roy*_*Art 6

我使用这种类型的声明:

const identity: { <T>(arg: T): T } = (arg) => arg;
Run Code Online (Sandbox Code Playgroud)

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

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

const identity: <T>(arg: T) => T = (arg) => arg;
Run Code Online (Sandbox Code Playgroud)