제네릭이있는 Typescript 화살표 함수의 구문은 무엇입니까?


192

타이프 스크립트 핸드북에는 현재 화살표 기능이 없습니다. 일반 함수는 다음과 같은 구문으로 일반적으로 입력 할 수 있습니다.

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

화살표 함수의 구문은 무엇입니까?

답변:


235

Robin이 참조한 구문을 설명하는 전체 예제 는 나를 위해 집으로 가져 왔습니다.

일반 함수

다음과 같은 것이 잘 작동합니다.

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

그러나 화살표 일반 기능을 사용하면 다음이 수행되지 않습니다.

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

해결 방법 : generic 매개 변수에서 extends를 사용하여 컴파일러가 일반 매개 변수임을 암시하십시오. 예 :

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

1
에 대해 사전 정의 된 제네릭 형식을 선언 할 수 const foo있습니까? 즉 type GenericFun<T, A=T> = (payload: A) => T;다음 확인 const foo: GenericFun제공하지 않고 일반적인 여전히 T유형을?
— ciekawy

@ ciekawy, AFAIK는 그렇지 않습니다. 제네릭은 어떤 의미에서 고차 유형을 허용하는 것에 관한 것입니다. 다른 유형 과 GenericFun<T, A=T>를 포함하는 세트를 정의합니다 . 일반적인 유형을 허용하면 직접 유형 약어를 구성하기 - 예를 들면 const를 - 그러나, 다른 특이성 예를 들어 요구에 의해 제공되는 정적 안전 침식하는 경향 또는 GenericFun<number>GenericFun<string>const foo: GenericFunconst foo: GenericFun<string>const foo: GenericFun<number>
— jbmilgrom을

7
두 번째 예는 .tsx파일 의 오류 일뿐입니다 (TypeScript + JSX). TypeScript 놀이터.ts 에서 볼 수 있듯이 파일 에서는 정상적으로 작동합니다 .
— danvk

47
최신 타입 스크립트 컴파일러는 const foo = <T,>(x: T) => x;JSX 모호성을 회피하기 위해 후행 쉼표 를 지원 합니다.
— 토마스

1
@danvk이 점은 TS 파일에서 JSX를 금지 한 사람들에게만 해당됩니다. 프로젝트가 TS 파일에서 JSX를 허용하도록 구성된 경우 여전히 "확장"또는 후행 쉼표가 필요합니다
— Matt

65

위의 예제가 혼란 스러웠습니다. React와 JSX를 사용하고 있으므로 시나리오가 복잡하다고 생각합니다.

화살표 제네릭을 나타내는 TypeScript Deep Dive 에서 설명을 얻었습니다 .

해결 방법 : 제네릭 매개 변수에 extends를 사용하여 컴파일러가 제네릭임을 암시하십시오.

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

9
그런 다음 "T extends any"는 void를 지원합니다.
— Mohamed Fakhreddine

48

.tsx파일 에 있다면 쓸 수 <T>는 없지만 작동합니다.

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

받는 반대로 extends {}해킹, 적어도이 해킹 의도를 유지합니다.


그들은이 행동을 고칠 계획입니까?
— Alexander Kim

이것에 대해 할 수있는 일이 많지 않다고 생각합니다. JSX와 Typescript의 일반적인 문법은 여기에 충돌합니다.
— mb21

1
환상적인-이것은 최고의 답변입니다. 완벽하게 작동하며 동작을 전혀 변경하지 않습니다!
— Geoff Davids

1
기본 유형 매개 변수 유형은 어떻습니까? const foo = <T = any,>(x: T) => x작동하지 않습니다 ...
— Mikhail Vasin

34

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})
               });
           };


3

와 인기 대답하면서 extends {}작품보다 더 extends any, 그것은이 강제 T객체로

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

이것을 피하고 타입 안전을 유지하려면 extends unknown대신 사용할 수 있습니다

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

1

이 유형의 선언을 사용합니다.

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

필요에 따라 함수에 추가 소품을 정의 할 수 있으며 경우에 따라 함수 본문을 일반 정의에서 깨끗하게 유지하는 데 도움이됩니다.

추가 소품 (네임 스페이스 종류)이 필요하지 않은 경우 다음과 같이 단순화 할 수 있습니다.

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

1

너무 늦었지만 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 의견에 설명 된 것처럼
— apollo

게시하기 전에 다른 솔루션을 읽어야합니다. 솔루션이 이미 설명과 함께 게시되었습니다. .tsx 파일이 아닌 .ts 파일 내에서만 작동합니다.
— Isaac Pak
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.