내용으로 건너뛰기
GaramX
사용자 도구
로그인
사이트 도구
검색
도구
문서 보기
이전 판
역링크
최근 바뀜
미디어 관리자
사이트맵
로그인
>
최근 바뀜
미디어 관리자
사이트맵
현재 위치:
home
»
typescript
»
generic
추적:
typescript:generic
이 문서는 읽기 전용입니다. 원본을 볼 수는 있지만 바꿀 수는 없습니다. 문제가 있다고 생각하면 관리자에게 문의하세요.
====== Generics ====== JavaScript는 타입 선언이 필요하지 않고, 따라서 특정 타입을 위해 만들어진 클래스나 함수도 타입 에러를 런타임에서 일으킬 뿐이다. 코드를 실행시키기 전까지는 함수와 클래스가 모든 타입에 대응한다. 따라서 JavaScript에서는 제네릭이란 말을 듣지 못 했다. ==== 제네릭을 사용하는 이유 ==== ''any''를 이용하여 구현하는 방법이 있겠으나 제네릭과는 차이가 있다. <code javascript> let data: any[] = []; function pushItem(item: any): void { any.push(item); } </code> ''data''의 타입이 any이므로 [0,'a string']라는 상이한 type을 가질 수 있다. <code javascript> let data: T[] = []; //generic type T를 갖는 배열 </code> 이제 data는 하나의 타입을 갖는 배열이 된다. ===== Generic Types ===== <code javascript> function identity<T>(arg: T): T { return arg; } </code> <code javascript> let myIdentity: <T>(arg: T) => T = identity; let a: <U>(arg: U): U = identity; let myIdentity: {<T>(arg: T): T} = identity; // Generic type parameter의 이름을 다르게 사용해도 됨 </code> ===== Generic interface ===== <code javascript> interface GenericIdentityFn { <T>(arg: T): T; } function identity<T>(arg: T): T { return arg; } let myIdentity: GenericIdentityFn = identity; let myIdentity: GenericIdentityFn<number> = identity; // type을 number로 고정시킴 </code> <WRAP center round info 60%> Generic interface이외에도 Generic class도 만들 수 있지만, generic enum이나 generic namespace를 만들 수 는 없다. </WRAP> ===== Generic Classes ===== <code javascript> class Generic<T> { zeroValue: T; add: (x: T, y: T) => T; } let myGenericNumber = new GenericNumber<number>(); myGenericNumber.zeroValue = 0; myGenericNumber.add = function(x, y) { return x + y }; </code> <WRAP center round important 60%> Generic class는 오직 객체에서만 generic 사용가능하다. 그렇기 때문에 class작업을 할 때 정적 멤버들은 generic사용이 안된다는 점을 유념하자 </WRAP> ===== Generic Constraints ===== 특정한 타입들(내부 메서드는 알고 있는)과 작동하는 generic함수를 만들고 싶을지 모른다. 예제에서 .length속성을 접근하고 싶었지만 모든 타입이 .length속성을 가지고 있는 것이 아니라서 컴파일러는 에러메세지를 보내준다. <code javascript> function loggingIdentity<T>(arg: T): T { console.log(arg.length); // error : T dosen't have .length return arg; } </code> any와 모든 타입과 작동하는 대신에 우리는 .length속성이 있는 모든 타입과 any와 작동하는 함수로 제한하고 싶을지도 모른다. 이 타입이 .length를 가지는 한 허용할 것할 것이고, .length멤버는 필수입니다. 이렇게 하기 위해서, 반드시 T가 무엇이 되어야 하는지 **제한**을 두어야 합니다. 제한을 두기 위해서, 제한을 구현시키는 interface을 만들 것이다. 여기서 .length속성이 있는 interface를 만들 것이고 그 다음 extends키워드를 통해 제한을 나타낸다. <code javascript> interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T console.log(arg.length); // Now we know it has a .length property, so no more error return arg; } </code> 이제 제한을 걸었기 때문에 아무 타입이나 작동하지 않는다. <code javascript>loggingIdentity(3); // Error, number doesn't have a .length property</code> 대신에 우리는 모든 type 요구조건이 충족된 값을 인자값으로 넘겨야 한다. <code javascript>loggingIdentity({length: 10, value: 3});</code> ===== Using Type parameters in Generic Constraints ===== 다른 type인수에 의해 제한되는 type인수를 선언한다. 예를 들자면, 주어진 이름으로 객체의 속성을 얻고 싶다고 하자. 실수로라도 객체에 존재하지 않는 다른 속성을 갖지 않도록 하고 싶다. 그래서 2개의 타입에 제한을 둘 것이다. <code javascript> function getProperty<T, K extends keyof T>(obj: T, key: K) { return obj[key]; } let x = { a: 1, b: 2, c: 3, d: 4 } getProperty(x, "a"); // Ok getProperty(x, "m"); // error: Argument of type 'm' isn't assignable to 'a' | 'b' | 'c' | 'd'. </code> ===== Using Class Types in Generics ===== Generic을 이용해서 Factory를 만들때, 클래스타입들을 그들의 생성자 함수에 의해 참조하는 것은 필수적입니다. <code javascript> function create<T>(c: {new(): T}): T { return new c(); } </code> 더 고급 예시는 클래스의 생성자 함수와 객체측 사이에서의 관계를 제한하고 추론하기 위해 프로토타입 속성을 사용한다. <code javascript> class BeeKeeper { hasMask: boolean; } class ZooKeeper { nametag: string; } class Animal { numLegs: number; } class Bee extends Animal { keeper: BeeKeeper; } class Lion extends Animal { keeper: ZooKeeper; } function createInstance<A extends Animal>(c: new() => A): A { return new c(); } createInstance(Lion).keeper.nametag; //typecheck! createInstance(Bee).keeper.hasMask; //typecheck! </code>
typescript/generic.txt
· 마지막으로 수정됨: 2025/04/15 10:05 저자
127.0.0.1
문서 도구
문서 보기
이전 판
역링크
맨 위로