2017-11-14 3 views
0

所定のインターフェイスインターフェイス:機能活字体 - インタフェースに対する試験方法、すなわちT [ 'methodNameの']

const b = (x: string) : number; 

目標考える

class A { 
    method(x:number) : string 
} 

- インタフェース

に対して機能をテスト

実現

type InterfaceKey = { 
    method: any 
}; 

function typecheck<T, K extends keyof InterfaceKey >(imp:() => T, d: T[K]) { 
//         K cannot be used to index type T^
    imp(); 
    return d; 
} 

typecheck(someclass, 555); // <-- type check _is actually works_ here 

// or 

function typecheck <T>(imp:() => T, d: any) { 
    imp(); 
    if(!d) { 
     let mock: T; 
     mock.default = d; // default does not exists on type T 
     return mock; 
    } 
    return d; 
} 

最初のアプローチが唯一の方法であるように見えますし、(Webstormではtscではなく)タイプチェックを実行しますが、コンパイルはしません。

関連:https://github.com/Microsoft/TypeScript/issues/15768

+0

あなたは何をしようとしているのかについて具体的に説明できますか?あなたは「テストする」という意味ですか? – dbandstra

+0

クラスメンバーと関数の間のインターフェースを一致させたい。つまり、InterfaceKeyからメソッド名を選択し、クラスTからシグネチャを選択し、一部の関数に対して型検査を行います。 –

答えて

0
//base interface 
interface MyInterface { 
    method: any 
} 

// check with defined method 
interface CheckD<T extends MyInterface> { 
    all(keys: {[P in keyof T]?: T[P]}): Check<T>; 

    onlyMethod<Ts extends {[K in keyof Ts]: Ts[K]} & T>(fn: Ts['method']): Check<T>; 
} 

// check without 
interface Check<T> { 
    all(keys: {[P in keyof T]?: T[P]}): Check<T>; 
} 

type CCD<T extends MyInterface > = CheckD<T>; 
type CC<T> = Check<T>; 

// magic 
function uncast(a: any): any{ 
    return <any>a; 
} 

// function overloading 
function load<K extends MyInterface>(a: K): CCD<K>; 
function load<T>(a: T): CC<T>; 

// type guards 
function load<T, K extends MyInterface>(a: T|K): CCD<K> | CC<T>{ 
    if ((<K>a).method) return <CCD<K>>uncast(a); 
    return <CC<T>> uncast(a); 
} 

// TEST 

var C1 = { 
    test: a => a + 1, 
    method: a => 5 
} 

var C2 = { 
    test: a => a + 1,  
} 

let a1 = load(C1); 
a1.all({ test: a => 1 }); 
a1.onlyMethod(55); // type error 

let a2 = load(C2); 
a2.all({ test: (a,b) => 1 }); // type error 
a2.all({ test2: a => 1 });// type error 
a2.onlyMethod(55); //no such method 

ので、実際には、結果は非常に理解しやすいです。

0

は、これが正しい方向に行きますか?

class someclass { 
    method(x: number): string { return null!; }; 
} 

const b = (x: number): string => null!; 

type InterfaceKey = { 
    method: any 
}; 

function typecheck<T extends InterfaceKey>() { 
    return <K extends keyof InterfaceKey>(d: T[K]) => {}; 
} 

// should fail if signature of someclass's `method` doesn't match that of `b` 
typecheck<someclass>()(b); 
+0

Not quite :)アイデアは、型だけですべてを解決することです、あなたは関数呼び出しを持っています。 –

+0

はい、しかし、関数呼び出しは何もせず、コンパイル時にエラーをキャッチします – dbandstra