본문 바로가기

TypeScript

(24)
타입의 호환성 - 열거형 다른 열거형으로부터 유래된 값끼리는 호환되지 않는다. enum Status { Ready, Waiting } enum Color { Red, Blue, Green } let status: Status = Status.Ready; status = Color.Green; // error 숫자 열거형 값은 `number`에, 문자열 열거형 값은 `string`에 할당 가능하다. ``` enum MyEnum { Zero, One = 1, Name = '김지혜' } const zero: number = MyEnum.Zero; const one: number = MyEnum.One; const name: string = MyEnum.Name; ```
타입의 호환성 - 제네릭 모든 타입 변수가 어떤 타입인지 알려진 경우 interface NotEmpty { data: T; } let x: NotEmpty; let y: NotEmpty; 어떤 타입인지 알려지지 않은 타입 변수가 있는 경우 const identity = function(x: T): T { // ... }; const reverse = function(y: U): U { // ... }; 이 때, identity와 reverse 함수의 타입에는 타입 변수가 남아 있다. 이럴 때에는 **아직 남아 있는 타입 변수를 모두 `any` 타입으로 대체하고 호환성을 판단**한다. 예를 들어 아래와 같은 할당은 허용된다.
타입의 호환성 - 클래스 class FacebookUser { constructor (id: string, private password: string) {} } class TwitterUser { constructor (id: string, private password: string) {} } let twitterUser: TwitterUser; let facebookUser: FacebookUser; twitterUser = facebookUser; `TwitterUser` 타입과 `FacebookUser`타입은 모두 `private password: string` 멤버를 갖는다. 비록 이름은 같지만 이 두 속성은 서로 다른 클래스에서 정의된 `private` 멤버다. 따라서 위와 같은 할당을 시도한다면 다음 타입 에러가 ..
타입의 호환성 - 함수 타입 매개변수 수가 같은 경우 할당 가능한 경우 const sum: Sum (sumFirst: number, sumSecond: number) => { return sumFirst + sumSecond; }; const multiply: Multiply = sum; // ok할당 불가능한 경우 interface Animal { animalProp: string }; interface Dog extends Animal { dogProp: number }; let f = (animal: Animal) => animal.animalProp; let g = (dog: Dog) => { doSomething(dog.dogProp) }; f = g;매개 변수 수가 다른 경우 할당하는 함수의 매개변수 수가 더 많은 경우 ..
타입의 호환성 - 객체 타입 interface User { name: string; height: number; } interface Pet { name: string; species?: string; } const user: User = { name: '안희종', age: 176 }; const puppy: Pet = { name: '해피' }; 아래 코드 실행하면 어떤 결과가 나올까? ``` const pet2: Pet = user; // ?? const user2: User = pet; // ?? ``` 두 가지 기준 User는 Pet에 할당 가능한가? Pet의 필수 멤버는 name 하나다. 같은 이름의 멤버가 User에도 존재한다. Pet의 name 멤버 타입은 string 이다(type M = ..
타입의 호환성 - 기본 타입 두 가지 다른 타입 A와 B에 대해, 모든 A 타입의 값을 B 타입의 값으로도 취급할 수 있는가? type OneDigitOdd = 1 | 3 | 5 | 7 | 9; const three: OneDigitOdd = 3; const num: number = three; 위의 코드는 `number` 타입의 값에 `OneDigitOdd` 타입의 값을 할당한다. 이 때, `OneDigitOdd` 타입이 가질 수 있는 값인 `1, 3, 5, 7, 9` 는 모두 `number` 에 속한다. `OneDigitOdd` 타입의 모든 값이 number 타입의 값이기도 하므로 위의 코드는 오류 없이 실행 된다. 즉, `OneDigitOdd` 타입은 `number` 타입에 할당 가능(assignable)하다. 반면 아래의 코..
인터페이스와 클래스의 관계 클래스의 인터페이스 구현 인터페이스는 본질적으로 값이 어떤 멤버를 반드시 가져야 하며 그 멤버들의 타입은 어때야 한다는 제약을 나타내는 수단이다. implements 키워드를 사용해 클래스가 이러한 제약을 따라야 함을 표현할 수 있다. interface Animal { legs: number; } class Dog implements Animal { legs: number = 4; } // Okay인터페이스의 클래스 확장 인터페이스 확장과 유사하게 extends 키워드를 사용해 클래스를 확장할 수 있다. 공식 문서에 있는 예제를 살펴보자. class Point { x: number; y: number; } interface Point3d extends Point { z: number; } const po..
추상 클래스 class 키워드 대신 abstract class 키워드를 사용해 추상 클래스를 선언할 수 있다. 일반 클래스는 extends 키워드를 사용해 추상 클래스를 확장할 수 있다. 추상 클래스는 인스턴스화가 불가능하다는 점에서 일반 클래스와 다르다. 또한 추상 클래스는 구현을 일부 포함할 수 있다는 점에서 인터페이스와 다르다. 공식 문서의 예제를 보자. abstract class Animal { move(): void { console.log("roaming the earth..."); } abstract makeSound(): void; } **가상 클래스를 확장하는 서브 클래스는 슈퍼 클래스의 모든 가상 메소드를 구현해야 한다**