2017-06-20 84 views
8

我使用TypeScript版本2.3.4。我想編寫一個接受必須具有指定字段的對象的函數。但是這個對象不應該包含任何其他字段。我怎樣才能做到這一點?TypeScript嚴格的類/接口

現在這隻適用於我定義對象內聯。但是,如果我使用額外字段的另一個對象 - 編譯器將允許它。什麼是完全錯誤的。

實施例:

function foo(arg: { a: string }) { // there is tons of fields actually 
    // ... 
} 

foo ({a: "qwerty"}); // No Error - ok 

foo ({a: "qwerty", b: 123}); // Error - ok 

let bar = { 
    a: "qwerty", 
    b: 123 
}; 

foo (bar); // No Error - NOT OK !!! 

相同的代碼可與接口,類類型聲明來所著 - 這是同樣的問題。

現在我必須手動從對象中提取字段,以確保沒有額外的字段。但是我不能在整個代碼中將這個解決方案傳播給1000個函數(我真的需要這個) - 這太亂了。我創建API包裝,我需要確保沒有傳遞給服務器的額外或錯誤的字段。

+0

看起來像是故意的。請參閱[此問題](https://github.com/Microsoft/TypeScript/issues/13444)和[this](https://github.com/Microsoft/TypeScript/issues/3755)以獲取更多討論。 – Saravana

+0

Saravana,是的,我讀過這篇文章,但在這些討論中沒有回答我的問題。我認爲避免接口的嚴格性會更好,但將其留給班級。 –

回答

2

你要求的是被稱爲「exact types」的功能。
它正在被考慮,也就是說,既沒有被拒絕也沒被接受,討論仍在繼續。

1

這是如何通過設計工作,我不知道你可以解決這個問題。 See the docs欲瞭解更多信息。

你也做錯了什麼 - 你不能100%確定發送到服務器的內容。只要瀏覽器對TS沒有任何瞭解,某些庫可以根據需要注入任何需要的請求。通過覆蓋XmlHttpRequest方法(這至少是angular的zone.js所做的)。

輕鬆打破你的意圖的另一種方法就像在任何參數前面使用<any>一樣簡單。

TypeScript旨在改善您的開發過程,但我不認爲它可以用於像您這樣的需求。這通常通過編寫適當的測試來涵蓋。

+0

當然我知道TS編譯成JS,沒有類或類型檢查!我需要在開發過程中保護其他開發人員的方法。這一切關於發展。真實案例: https://codepen.io/HarryBurns/pen/LLWoVa.typescript –

1

有「是」的一種方式,但你必須自己實現它。它被稱爲「用戶定義類型衛士」,它看起來像這樣:

interface Test { 
    prop: number; 
} 

function isTest(arg: any): arg is Test { 
    return arg && arg.prop && typeof(arg.prop) == 'number'; 
} 
+0

最好使用Reflection(請參閱http://blog.wolksoftware.com/decorators-metadata-reflection-in-typescript-from -novice-to-expert-part-4),所以它會更短,就像'check (myObject)'。或者,就我而言,它是'挑選(myObject)'。像下劃線/ lodash'pick'函數一樣工作。 –

2

Necromancing。

type foo = { 
    a:string; 
    b:number; 
    opt?:string; 
} 


function test(obj:foo) 
{} 

test({ a:"", b:123, e:"produceError"}); 

以及強制它是一個對象,如果所有的參數都是可選的:
它與打字稿2.4即將

function test(obj:foo & object) 
{} 

如果你想傳遞一個字符串或其他對象的類型:

function test(obj: string | foo & object) 
{}