[英]Typescript: Input object has subset of keys of an interface
我希望能夠指定函數的輸入對象應僅包含現有接口中存在的鍵(它不需要具有所有鍵)。
interface Group {
name: string
}
interface Person {
id: number
name: string
email: string
age: number
}
interface AddedProperties {
groups: Group[]
}
function createPerson<D extends object>( // <-- Should convey, D is an object with some keys of Person
personData: D
): D & AddedProperties {
return Object.assign({}, personData, { groups: [] })
}
interface NameAndAge {
name: string
age: number
}
// Valid: Should be valid
const person: NameAndAge = createPerson({ name: "bob", age: 5 })
// Valid: Should be invalid as 'personality' doesn't exist on Person
const person2 = createPerson({ name: "bob", age: 5, personality: "cheerful" })
打字稿可能嗎?
一種簡單的方法是使用Partial<>
:
function createPerson(
personData: Partial<Person>
): Partial<Person> & AddedProperties {
return { ...personData, groups: [] };
}
Partial
采用一種類型,並使所有成員都是可選的,因此允許您指定該類型的屬性的任何子集。
這種類型的缺點是返回的類型不知道您輸入的內容:
createPerson({name: "Bob", age: 5}); // OK
createPerson({name: "Bob", gender: "male"}); // Type error
createPerson({name: "Bob"}).name; // OK
createPerson({name: "Bob"}).age; // OK :-(
如果您也想避免這種情況,請查看我的其他答案。
好的,經過一些研究,我現在找到了更好的答案:-)不過,我也將保留其他答案。 您可以執行以下操作:
function createPerson<D extends keyof Person>(
personData: Pick<Person, D>
): Pick<Person, D> & AdditionalProperties {
return Object.assign({}, personData, {groups: []});
}
這允許personData
只是Person
personData
集,並且返回類型將具有完全相同的結構以及AdditionalProperties
:
createPerson({name: "Bob", age: 5}); // OK
createPerson({name: "Bob", gender: "male"}); // Type error
createPerson({name: "Bob"}).name; // OK
createPerson({name: "Bob"}).age; // Type error
它是如何工作的? 泛型D extends keyof Person
將再次允許添加新字段,我們希望避免這樣做。 我們不能在泛型類型參數的定義中處理此問題(因為我們僅在那里進行extends
),而是將實際函數參數限制為
personData: Pick<Person, D>
這將輸入限制為僅出現在D
的Person
那些屬性。 我們使用與返回類型相同的類型(與AdditionalProperties
相交)。
您可以在這里查看它的運行情況:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.