반응형
제네릭 타입 추론
대부분의 상황에서 TypeScript는 제네릭 타입을 잘 추론해 냅니다.
function map<T,U>(array: T[], f: (item: T) => U): U[] {
let result = []
for (let i = 0; i < array.length; i++){
result[i] = f(array[i])
}
return result
}
map(
['a', 'b', 'c'], // T 타입의 배열
_=> _ === 'a' // U 타입을 반환하는 함수
)
위의 코드 map 함수를 함수 아래처럼 호출하면 TypeScript는 T를 string으로, U를 boolean으로 추론합니다.
그러나 제네릭도 명시적으로 지정할 수 있습니다. 제네릭 타입을 명시할 땐 모든 필요한 제네릭 타입을 명시하거나 반대로 아무것도 명시해선 안 됩니다.
map<string, boolean>(
['a', 'b', 'c'],
_=> _ === 'a'
)
map<string>( // 2개의 형식 인수가 필요한데 1개를 가져왔습니다.ts(2558)
['a', 'b', 'c'],
_=> _ === 'a'
)
TypeScript는 추론된 각 제네릭 타입을 명시적으로 한정한 제네릭에 할당할 수 있는지 확인합니다. 할당할 수 없으면 에러가 발생합니다.
// boolean은 boolean | string에 할당할 수 있으므로 에러 안남
map<string, boolean | string>(
['a', 'b', 'c'],
_=> _ === 'a'
)
map<string, number>(
['a', 'b', 'c'],
_=> _ === 'a' // 'boolean' 형식은 'number' 형식에 할당할 수 없습니다.ts(2322)
)
TypeScript는 제네릭 함수로 전달한 인수의 정보를 이용해 제네릭의 구체 타입을 추론하므로 때로는 아래와 같은 상황이 벌어질 수 있습니다.
let promise = new Promise(resolve =>
resolve(45)
)
promise.then(result => // {}로 추론함. error TS2362: 수학 연산의 왼쪽 연산자는 'any', 'number', 'bigint', 'enum' 타입 중 하나여야 함
result*4
)
TypeScript가 result를 {}로 추론한 이유는 TypeScript에 충분한 정보를 제공하지 않았기 때문입니다.
TypeScript는 제네릭 함수의 인수에만 의지하여 제네릭 타입을 추론하는데, 인수가 아무것도 없으니 기본적으로 T를 {}로 간주한 것입니다.
Promise의 제네릭 타입 매개변수를 명시해서 위의 문제를 해결할 수 있습니다.
let promise = new Promise<number>(resolve =>
resolve(45)
)
promise.then(result =>
result * 4
)
반응형
'👶 TypeScript' 카테고리의 다른 글
한정된 다형성 (0) | 2023.01.13 |
---|---|
제네릭 타입 별칭 (0) | 2023.01.13 |
제네릭을 어디에 선언할 수 있을까? (0) | 2023.01.13 |
언제 제네릭 타입이 한정되는가? (0) | 2023.01.12 |
다형성 (0) | 2023.01.12 |