簡體   English   中英

Typescript中具有嚴格形狀約束的泛型

[英]Generic type with strict shape constraint in Typescript

當查看以下代碼時:

type Test<T extends {a: number}> = ...doing something with keyof T...

Test<{a:1}> // ok
Test<{a:1, b:1}> // ok, but I want this to fail due to having 'b';

有什么辦法可以使第一個還可以,但嚴格限制形狀並不允許額外的屬性,則不能使第二個還可以。

您不能直接使用它,但是可以通過使用條件類型來確保該類型如果具有額外的屬性,則不會真正可用:

type Test<T extends { a: number }> = Exclude<keyof T, keyof { a: number }> extends never ?  T : "T must be exactly of type { a: number }";
let ok: Test<{ a: number }> = { a: 10 }; // ok
let nok: Test<{ a: number, b: number }> = { a: 1, b: 2 }// nok; Type '{ a: number; b: number; }' is not assignable to type '"T must be exactly of type { a: number }"'.

進一步討論

Typescript會在直接分配對象文字時檢查額外的屬性,因此這將是一個錯誤:

let a: { a: number } = { a: 1, b: 1 }; // error Object literal may only specify known properties...

但是如果類型兼容(即具有更多屬性),則允許從其他來源進行賦值

let ab = { a: 1, b: 1 };
let a: { a: number } = ab // ok

上面的類型(或它的變體)可以幫助我們創建一個不希望多余屬性且可以推斷泛型參數的函數:

function create<T extends { a: number }>(p: T & (Exclude<keyof T, keyof { a: number }> extends never ?  T : "T must be exactly of type { a: number }")) : T{

}
create({ a: 1, b: 1 }); //Type '{ a: number; b: number; }' is not assignable to type '"T must be exactly of type { a: number }"'.
create({ a: 1 }); //ok

但第二種方法不行,因為嚴格限制形狀並且不允許額外的屬性。

不適用於泛型。 將每個T替換為其值,例如,用type Test<T extends {a: number}> = T替換type Test = {a: number}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM