簡體   English   中英

打字稿:輸入對象具有接口鍵的子集

[英]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>

這將輸入限制為僅出現在DPerson那些屬性。 我們使用與返回類型相同的類型(與AdditionalProperties相交)。


您可以在這里查看它的運行情況:

暫無
暫無

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

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