function logText<T>(text: T): T {
return text;
}
// #1
const text = logText<string>("Hello Generic");
// #2
const text = logText("Hello Generic");
function logText<T>(text: T[]): T[] {
console.log(text.length); // 제네릭 타입이 배열이기 때문에 `length`를 허용합니다.
return text;
}
interface GenericLogTextFn<T> {
(text: T): T;
}
function logText<T>(text: T): T {
return text;
}
let myString: GenericLogTextFn<string> = logText;
class GenericMath<T> {
pi: T;
sum: (x: T, y: T) => T;
}
let math = new GenericMath<number>();
이넘 타입은 number 타입과 호환되지만 이넘 타입끼리는 호환되지 않습니다.
enum Status { Ready, Waiting };
enum Color { Red, Blue, Green };
let status = Status.Ready;
status = Color.Green; // Error
클래스 타입은 클래스 타입끼리 비교할 때 스태틱 멤버(static member)와 생성자(constructor)를 제외하고 속성만 비교합니다.
class Hulk {
handSize: number;
constructor(name: string, numHand: number) { }
}
class Captain {
handSize: number;
constructor(numHand: number) { }
}
let a: Hulk;
let s: Captain;
a = s; // OK
s = a; // OK
제네릭은 제네릭 타입 간의 호환 여부를 판단할 때 타입 인자 가 속성에 할당 되었는지를 기준으로 합니다. 예시 코드를 보겠습니다.
interface Empty<T> {
}
let x: Empty<number>;
let y: Empty<string>;
x = y; // OK, because y matches structure of x
위 인터페이스는 일단 속성(member 변수)이 없기 때문에 x와 y는 같은 타입으로 간주됩니다.
그런데 만약 아래와 같이 인터페이스에 속성이 있어서 제네릭의 타입 인자가 속성에 할당된다면
얘기는 다릅니다.
interface NotEmpty<T> {
data: T;
}
let x: NotEmpty<number>;
let y: NotEmpty<string>;
x = y; // Error, because x and y are not compatible
인터페이스 NotEmpty에 넘긴 제네릭 타입<T>이 data 속성에 할당되었으므로
x와 y는 서로 다른 타입으로 간주됩니다.
** 출처
https://joshua1988.github.io/ts/guide/type-compatibility.html#generics