網站搜尋

typescript - 一個有類型的函數可以遞歸訪問物件屬性嗎?


有沒有一個好的方法在 TypeScript 中為一個會遞迴訪問物件屬性的函數進行型別定義?這裡有一個手動編碼的範例,深入兩層:

function deepProp<T, K extends keyof T>(obj: T, prop1: K, prop2: keyof T[K]) {
    return obj[prop1][prop2];
}

// Example use
const obj = {
    user: {
        pets: [{
            toys: [{
                name: "Toughy",
                price: 1999
            }]
        }]
    }
} as const
deepProp(obj, "user", "pets");

但我正在尋找一個好方法,可以在 deepProp 函數中接受任意數量的 props,以便深入到所需的深度。我想像那個函數的簽名可能像這樣 function deepProp(obj, ...props) { }。有沒有一個好方法來做到這一點?謝謝!

答案#1

對於任意數量的鍵是不可能的,但你可以為你的需求做一些類似 lodash 的 get 的東西。

也有可能以某種遞歸的方式使用這個函數。

提到的 _.get 範例(其類型支援最多 4 個鍵):

const obj = {
    user: {
        pets: [{
            toys: [{
                name: "Toughy",
                price: 1999
            }]
        }]
    }
} as const

const toy1 = _.get(obj, ["user", "pets", 0, "toys"]); // correct type
const toy2 = _.get(obj, ["user", "pets", 0, "toys", 0]); // any :(
const toy3 = _.get(_.get(obj, ["user", "pets", 0, "toys"]), [0]); // correct type :)