Typescript 제네릭

10255 단어 typescript
소프트웨어 엔지니어링의 주요 부분은 잘 정의되고 일관된 API를 가질 뿐만 아니라 재사용이 가능한 구성 요소를 구축하는 것입니다. Typescript의 Generics를 사용하면 여러 유형에서 작동하는 구성 요소를 만들 수 있습니다.

제네릭을 사용하는 가장 기본적인 예는 배열입니다. Typescript를 사용하여 배열을 채울 유형을 정의할 수 있습니다.

const strArr: string[] = ["one", "two", "three"];

strArr.push(1) // This would error
string[]를 사용하여 함수에서 arg 유형을 정의하는 경우 예상대로 arg가 문자열 배열이 아니면 오류가 발생합니다. 그러나 다른 유형의 배열을 처리할 수 있는 함수가 필요할 수 있는 시나리오가 있습니다. 다음 예를 고려하십시오. getLast는 배열의 마지막 항목을 반환합니다.

const getLast = (arr: string[]): string => {
    return arr[arr.index - 1];
}

// 'test2'
console.log(getLast(['test', 'test2']);

// Will error
console.log(getLast([1,2,3]);

여기서 알 수 있듯이 문자열만 포함하도록 전달할 수 있는 배열getLast로 제한됩니다. 그러나 모든 유형을 포함하는 배열의 마지막 항목을 반환하려는 것은 완벽하게 합리적일 것입니다. 여기서 값이 아닌 유형에 대해 작동하는 특수 변수인 유형 변수를 사용할 수 있습니다.

const getLast = <T>(arr: T[]): T => {
        return arr[arr.length - 1]; 
}

위에서 볼 수 있듯이 getLast에 전달되는 배열의 유형을 유형 변수T로 정의할 수 있습니다(참고 - T는 유형 변수의 일반적인 이름이지만 모든 이름을 사용할 수 있음). Typescript는 반환 유형도 인식합니다. 이것은 위의 것을 일반 함수로 바꿉니다. 다른 유형의 함수를 호출하기 위한 구문은 다음과 같습니다.

const numOutput = getLast<number[]>([1,2,3]) // output will be of type 'number'(3)

const strOutput = getLast<string[]>(['a','b','c']) // output will be of type 'string'('c')

제네릭 함수를 생성할 때 하나 이상의 유형 변수를 사용할 수 있습니다.

cont makeArr = <X, Y>(x: X, y: Y): [X, Y] => {
    return [x, y];
}

const v = makeArr<number, string>([1,'a']); // returns type ['number', 'string']

// Types can be inferred by Typescript, <number, number> is not necessary.
const v2 = makeArr(2,3) // returns type ['number', 'number']

다른 객체 유형에서 유형 변수를 확장하는 것이 가능합니다. .length 속성이 있는 유형에서만 작동하는 함수를 만들고 싶다면. 그렇게 하려면 요구 사항을 T에 대한 제약 조건으로 나열해야 합니다.

그렇게 하기 위해 우리는 우리의 제약을 설명하는 인터페이스를 만들 것입니다. 여기에서 단일 .length 속성이 있는 인터페이스를 만든 다음 이 인터페이스와 extends 키워드를 사용하여 제약 조건을 나타냅니다.

interface WithLength {
    length: number
}

function echo<T extends WithLength>(arg: T): T {
    console.log(arg.length);  // arg has a .length property, so no error
    return arg;
}

인터페이스가 있는 제네릭



제네릭을 사용하여 코드에서 보다 유연한 인터페이스를 생성할 수 있습니다. 구문은 위의 예와 유사합니다. 이것은 HTTP 요청과 같이 객체 모양의 일부만 확신할 수 있는 경우에 유용합니다.

interface HttpResponse<T = any> {
    success: boolean
    error?: string
    data: T
}

type StringResponse = HttpResponse<string>

그런 다음 위의 내용을 함수에서 사용하여 코드 기반에서 반환된 데이터를 더 많이 제어할 수 있습니다.

interface Person {
    name: string
    age: number
}

const makeRequest = async<T = any>(): Promise<HttpResponse<T>> => {
    const response = await // some logic
    return response;
}

const data = makeRequest<Person>() // resolves with data as a Person

유용한 기사



Official Typescript docs

좋은 웹페이지 즐겨찾기