2017-08-29 48 views
1

考慮以下幾種類型:字符串文字參數作爲編譯時類型名稱

interface ActiveXObject { 
    new(progid: 'Word.Application'): Word.Application; 
    new(progid: 'Word.Document'): Word.Document; 
} 

其採取各種字符串文本,並返回相應類型:

declare namespace Word { 
    interface Application { } 
    interface Document { 
     Save(): void; 
    } 
} 

如下我可以寫多個重載。因此,下面可能不會編譯:

var doc = new ActiveXObject('Word.Document'); 

//compilation error here -- Word.Document doesn't have this method 
doc.BadMethod(); 

是否有可能寫一個過載其返回類型爲類型的字符串字面所指?

事情與此類似:

interface ActiveXObject { 
    new(progid: string): typefrom(progid); 
} 

,編譯器將標記爲不可識別的類型如下:

var nonexistentType = new ActiveXObject('Word.NonexistentType'); 
+0

有趣的問題。相關/可能的重複:[動態加載打字稿類 - 反射Typescript](https://stackoverflow.com/questions/15338610/dynamically-loading-a-typescript-class-reflection-for-typescript)和 [如何將字符串值轉換爲在Angular 2中鍵入](https://stackoverflow.com/questions/35356988/how-to-convert-a-string-value-to-type-in​​-angular-2) – Pac0

+0

@ Pac0 Both問題涉及在運行時從字符串創建實例;我對編譯時感興趣。 AFAICT,所有的答案要麼將結果轉換爲明確的類型,要麼只是使用'any'。 –

+0

是的,我沒有標記你的帖子,並正在閱讀這些。恐怕沒有優雅簡單的答案,只要你願意。但我不是專家,所以我不會將我的意見轉化爲答案。 – Pac0

回答

3

您可以利用類型映射和查找類型。不過,你仍然需要聲明一種查找類型。

link

declare namespace Word { 
    interface Application { } 
    interface Document { 
     Save(): void; 
    } 
} 
type Mapping = { 
    Application: Word.Application, 
    Document: Word.Document 
} 
interface ActiveXObject { 
    new<K extends keyof Mapping>(k: K): Mapping[K] 
} 

var doc = new ActiveXObject('Document'); 

//compilation error here -- Word.Document doesn't have this method 
doc.BadMethod(); 

如果你可以定義命名空間的Word導出類,你有更漂亮的把戲。

declare namespace Word { 
    export class Application { } 
    export class Document { 
     Save(): void; 
    } 
} 

interface ActiveXObject { 
    new<K extends keyof typeof Word>(k: K): (typeof Word)[K]['prototype'] 
} 

var doc = new ActiveXObject('Document'); 

doc.BadMethod(); // error 
doc.Save(); // ok 
+0

我正在考慮這個問題,特別是因爲我看到它在'lib.d.ts'中用於'createElement'簽名。我將不得不使用接口而不使用別名,因爲這些映射可能分佈在多個文件中,而且需要合併。 (小點 - 在我的具體情況下,名稱空間也必須包含爲映射類型的鍵。) –

+2

嗨@ZevSpitz,我想出了一個甚至需要更少重複的技巧。一探究竟。 –

相關問題