해결된 질문
작성
·
240
·
수정됨
1
extends로 타입을 제한하면 string이나 number가 아닌 해당 값으로 추론되는 이유가 무엇인지 잘 와닿지 않아서요😂
제한을 하나 안 하나 제네릭에 string 혹은 number로 추론이 되어야 하지 않나 싶은데,
T extends object | [] 이렇게 제한을 걸면 string이나 number처럼 정확히 추론이 되지 않구요😂
타입스크립트는 extends로 제한을 걸면 구체적으로 추론을 해주는 이유가 뭔지 궁금하네요🤔
답변 2
0
0
안녕하세요 우선 답부터 말씀드리면 말씀하신대로 extends string | number
빼면 추론이 제대로 되어야 하는게 맞습니다.
T extends object | [] 이렇게 제한을 걸면 string이나 number처럼 정확히 추론이 되지 않구요 😂
정확히 추론이 안된다는 것이 어떤 의미인지 제가 이해를 못했지만 extends string | number
를 빼면
error1
은
{
output: {
a: number
}
}
로 추론이 되고,
error2
는
{
output: number[]
}
로 추론이 되네요.
이 문제의 의도는 inferItemLiteral
에 string 또는 number만 허용하고 나머지 타입들은 허용하지 않게 하는게 목적이었습니다. 그래서 그런 타입 제한을 하게 된 것입니다. (노란색 사각형 영역처럼 object나 array 넘기면 타입 에러가 발생하도록)
아하 질문하신 의도를 이제 알았습니다! 제가 생각나는 방법은 여러가지가 있는데
첫번째 방법
tuple
로 추론하게 하고 싶은 거라면 가장 간단한 방법은 다음과 같이 할 수 있겠네요.
<T extends object | [any, ...any]>
이렇게 하시면 원하는 의도대로 추론이 될 것입니다. 그런데 이 방법의 단점은
const result1 = inferItemLiteral([1,2,"hello"])
위와 같이 number 뿐만 아니라 string "hello" 이 들어올 수 있게 허용해준다는 것이 있을 것 같네요.
두번째 방법
<T extends object | [...any]>
const result1 = inferItemLiteral([1,2,3] as [number, number, number])
type asserts 를 이용해서 array가 아니라 명시적으로 tuple 이라는 것을 알려줄 수 있는 방법도 있습니다.
세번째 방법
<T extends object | [...any]>
const error2 = inferItemLiteral([1, 2] as const);
뒤에 as const
를 붙이게 되면 두번째 방법보다 더욱 쉽게 해결할 수 있겠네요
넵 문제의 의도는 이해했습니다🙂
제가 의문스러운 건
{ output: [1,2,3] }으로 기대했는데 { output: number[] }가 결과값으로 나온 게 왜 그런건지 궁금해서 질문을 드렸습니다🙂
강의 진도를 더 나가다보면 왜 그런지 이해가 될까요?