2017-12-15 1 views
1

다른 JS 개발자와 마찬가지로, 저는 TypeScript 컴파일러가 이해할 수있는 정적 인 방법으로 작성하는 것에 다소 새로운 생각이 들었습니다. 나의 기본적인 유스 케이스는 REST 엔드 포인트에 액세스하기 위해 일반 클래스에서 사용 가능한 조치를 사용자 정의하는 것이다. 동적으로 생성자 인수를 기반으로하는 기본 클래스에 메서드/소품을 추가 할 수 있지만 동적으로 (당연히) intellisense를 부정확하게 만듭니다. 나는 내가이 잘못에 대해 생각하고 있다는 것을 알고 있으며, 내가 원하는 것을 성취하기위한 다른 패러다임이있다. 컴파일러가 이해하는 방식으로 하위 클래스의 기본 클래스를 사용자 정의 할 수 있습니까? 여기 조건부로 기본 클래스에 메서드/소품을 지정하십시오.

내가 노력하고있어입니다 :

class Endpoint<T> { 
    constructor(
     methods: Array<'GET' | 'CREATE'> 
    ) { 
     // Conditionally add methods to the endpoint based on what was passed in 
     if (methods.includes('GET')) { 
      this.get = function get(id: string): Promise<T> { 
       return new Promise<T>(resolve => resolve()); 
      }; 
     } 
     if (methods.includes('CREATE')) { 
      this.create = function create(body: T): Promise<T> { 
       return new Promise<T>(resolve => resolve()); 
      }; 
     } 
    } 

    public get?: (id: string) => Promise<T>; 
    public create?: (body: T) => Promise<T>; 
} 

class User extends Endpoint<IUser> { 
    constructor() { 
     super(['GET']); 
    } 
} 

let u = new User(); 
// u.create will get transpiled away, but still shows up in intellisense 
+2

일종의 추상 부모 클래스를 구현하려고하십니까? 그런 다음 원하는 기본 클래스를 정의하고 그 클래스에서 확장 된 클래스의 구현에 필요한 추가 인터페이스를 제공하지 않는 이유는 무엇입니까? – Icepickle

+0

나는 잘 모르겠다. 'class User extends Endpoint 은 IGettable '을 구현합니까? –

+0

또는'let u = 새 사용자()를 IGettable '로 사용 하시겠습니까? 그리고 인스턴스의 기능들의 교차를 위해'IGetCreate '과 같은 확장 인터페이스를 정의 할 수 있습니까? 그것은 작동하는 것 같습니다. –

답변

1
이 코드를 단축 할 수있을 것 그리고 그것은 꽤 아니지만, 기본적인 아이디어는 타이프 2.2에 도입 된 mixins 사용하는 것입니다

:

class Endpoint<T> { 
} 

type Constructor<T> = new(...args: any[]) => T; 

function Gettable<T, U extends Constructor<Endpoint<T>> = typeof Endpoint>(Base: U) { 
    return class extends Base { 
     get(id: string): Promise<T> { 
      return new Promise<T>(resolve => resolve()); 
     } 
    } 
} 

function Createable<T, U extends Constructor<Endpoint<T>> = typeof Endpoint>(Base: U) { 
    return class extends Base { 
     create(body: T): Promise<T> { 
      return new Promise<T>(resolve => resolve()); 
     } 
    } 
} 

class User extends Gettable<IUser>(Endpoint)<IUser> { 
} 

const u = new User(); 
u.get("id"); // ok 
u.create(); // error, method doesn't exist 
관련 문제