타입스크립트 angle brackets, 꺾쇠 괄호 <>
타입스크립트의 angle brackets, 꺾쇠 괄호 <>
노마드코더 타입스크립트 10일차 과제는 abstract classes, generics 그리고 overloading 을 이용해 fake API를 만드는 과제다.
과제를 진행하는도중 타입스크립트의 다양한 타입 형태가 나를 헷갈리게 한다.
abstract class AbLocationStroage<T> {
[key: string]: T
}
/// LocalStorage를 흉내낸 class
class LocalStorageAPI<T> {
private stroage: AbLocationStroage<T> = {}
}
setItem(key: string, value: T) {
if (this.stroage[key]) {
console.log(`${key} already exists.`)
}
else {
this.stroage[key] = value
}
}
스토리지 생성자의 AbLocationStorage에 붙은
setItem의 2번째 인자 타입의 T는 LocalAPI클래스의 제네릭을 받아온다..라고는 이해했지만,
제네릭 외에 tsx를 쓰다보면 꺾쇠가 자주 보여 혼동되기에 정리해보았다.
타입스크립트의 < SOMETHING > 문법은 다음과 같이 쓰인다.
Type Parameters
타입파라미터는 제네릭 형식 참조 또는 제네릭 함수 호출에서 바인딩되는 실제 유형을 나타냅니다
클래스, 인터페이스, 함수들의 콜시그니쳐와 정의에 쓰인다.
function heat<T>(foot:T): T { //^^^^^ Type parameter list return food; } class Pizza<T, E extends Cheese> { //^^^^^^^^^^^^^^^^^ Type parameter list toppingA:T; toppingB:E; }
Type Arguments
제네릭 타입과 제네릭 함수를 레퍼런스한다.
var pizza: Pizza<Pepperoni, Mozzarella>; //^^^^^^^^^^^^^^^^^^^^^^^ Type argument list pizza = heat<{toppingA: Pepperonu, topingB: Mozzarella}(ingredients) //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Type argument list
Parameter는 함수 정의에 있는 변수
Argument는 함수에 실제로 전달되는 값이다.
Type Parameter는 제네릭에서 타입 선언에 대한 blue print, place holder.
Type Arguments는 제네릭을 parameterize하는데 사용되는 실제 타입이다.
Type Assertions
TypeScript에서는 시스템이 추론 및 분석한 타입 내용을 우리가 원하는 대로 얼마든지 바꿀 수 있습니다. 이때 "타입 표명(type assertion)"이라 불리는 메커니즘이 사용됩니다. TypeScript의 타입 표명은 프로그래머가 컴파일러에게 내가 너보다 타입에 더 잘 알고 있고, 나의 주장에 대해 의심하지 말라고 하는 것과 같습니다.
공식문서에서 봤을때 가장 이해가 안되었던 부분. UnaryExpression(단항표현식) 으로 정의되고 사용된다. 주로 자바스크립트를 타입스크립트로 포팅할때 사용되는 경우가 많다고 한다.
타입스크립트에서 훅을 사용할때 타입에러를 뱉는경우
as
로 처리했던 경우를 떠올리면 될듯..var foo = {}; foo.bar = 123; // 오류: 속성 'bar'가 `{}`에 존재하지 않음 foo.bas = 'hello'; // 오류: 속성 'bar'가 `{}`에 존재하지 않음 //// 위와 같은 상황에서 interface Foo { bar: number; bas: string; } /// 인터페이스를 추가해주고 var foo = {} as Foo; //// foo 의 타입을 as를 통해 Foo 표명해주면 foo.bar = 123; foo.bas = 'hello'; // Ok.
위와 같은 방식엔 꺾쇠를 사용하지 않는다. 그렇다면 왜 이 항목에?
실제로는 꺾쇠를 사용한 syntax를 썼어야하는데, JSX에서 문법적으로 모호해지기에
as Foo
와 같이 사용하는 것이 권장된다고 한다.// 본래 권장되던 방식 var foo: any; var bar = <string> foo; // 이제 bar의 타입은 "문자열"입니다
// 아래와 같은 JSX에서 component인지 type assertion인지 문법적으로 모호해진다. var foo = <string>bar; </string>
마지막으로 jsx 표현이다.
- documented 된 스펙은 아니다.
<JSXElementName JSXAttributes(optional) />
으로 쓴다.
- documented 된 스펙은 아니다.
공부를 하고나니 , 첫 코드에 쓰인 T들을 설명할수 있게 된다.
abstract class AbLocationStroage<T> {
// ^^^ Type paramter
[key: string]: T
// ^^^ Type -capture the one the user provides
}
class LocalStorageAPI<T> {
// ^^^ Type paramter
private stroage: AbLocationStroage<T> = {}
// ^^^ Type paramter
}
setItem(key: string, value: T) {
// ^^^ Type
}
}
[타입스크립트딥다이브