我過去使用 ES6 創建了一個通用函式,并希望在新的 React Typescript 專案中重用它。
該函式稱為 getNestedValuesFromObject 并從物件和(深層)嵌套物件中檢索資料。
const getValueFromNestedObject = (objectPath, baseObject) => {
if (typeof objectPath !== 'string') return undefined;
return objectPath
.split('.')
.reduce((object, key) => (object && object[key] !== 'undefined' ? object[key] : undefined),
baseObject);
};
export default getValueFromNestedObject;
并且可以如下使用:
const testObject = {
exampleString: 'string',
nestedObject: {
exampleNumber: 1,
nestedNestedObject: {
exampleArray: [1, 2, 3],
}
}
}
const arrayFromNestedNestedObject = getValueFromNestedObject('nestedObject.nestedNestedObject', testObject);
你能幫忙輸入這個函式嗎?顯然 objectPath 是字串,而 baseObject 也可以是泛型,也可以是回傳型別。
uj5u.com熱心網友回復:
這種函式的問題在于它本質上不是型別安全的。您將物件路徑作為字串提供,假設該字串對給定物件有效(并且無法避免這種假設),并回傳您最終得到的任何值。FWIW,我建議不要使用它。相反,使用可選鏈接(并且在需要時,無效合并):
const arrayFromNestedNestedObject = testObject.nestedObject?.nestedNestedObject;
// or
const arrayFromNestedNestedObject = testObject.nestedObject?.nestedNestedObject ?? defaultValue;
這樣,您就可以進行型別檢查。
但是如果你想使用這個函式:
正如你所說,
path將string。baseObject可能必須非常開放,例如{[key: string]: any}.回傳值有問題。它可以是任何東西。
對于回傳值,您基本上有兩個選擇:
函式回傳值可能是可怕的
any.該函式可以接受一個必需的型別引數,說明您期望的結束型別。
他們都有優點和缺點。好處any是,你可以將它分配給任何東西。所以如果你有:
let num: number = getValueFromNestedObject("the.number", obj);
它會作業。缺點是即使函式找到的值不是數字,它也會作業,因此您不會收到編譯錯誤,但運行時行為(可能)是錯誤的。
所需的泛型引數有很多相同的問題:如果您認為結果將是number并執行:
let num = getValueFromNestedObject<number>("the.number", obj);
...事實并非如此,您再次沒有收到編譯錯誤,但運行時行為不好。
為了完整起見,這里是any作為回傳型別的函式:
const getValueFromNestedObject = (objectPath: string, baseObject: {[key: string]: any}): any => {
if (typeof objectPath !== 'string') return undefined;
return objectPath
.split('.')
.reduce((object, key) => (object && object[key] !== 'undefined' ? object[key] : undefined),
baseObject);
};
游樂場鏈接
為了緩解回傳型別的問題,您可以考慮使用多個函式:
getStringFromNestedObjectgetNumberFromNestedObjectgetBooleanFromNestedObjectgetObjectFromNestedObject
...它們都是上述內容的包裝器,但具有特定的回傳型別:
const getStringFromNestedObject = (objectPath: string, baseObject: {[key: string]: any}): string => {
const result = getValueFromNestedObject(objectPath, baseObject);
if (typeof result !== "string") {
throw new Error(`Invalid assertion, ${objectPath} didn't result in a string`);
}
return result;
};
它可以被多載以允許undefined:
function getStringFromNestedObject(objectPath: string, baseObject: {[key: string]: any}, allowUndefined: true): string | undefined;
function getStringFromNestedObject(objectPath: string, baseObject: {[key: string]: any}, allowUndefined: false): string;
function getStringFromNestedObject(objectPath: string, baseObject: {[key: string]: any}, allowUndefined = false): string | undefined {
const result = getValueFromNestedObject(objectPath, baseObject);
if (typeof result === "undefined" && allowUndefined) {
return result;
}
if (typeof result !== "string") {
throw new Error(`Invalid assertion, ${objectPath} didn't result in a string`);
}
return result;
}
等等。
但同樣,我建議使用可選鏈接和/或無效合并,以便您因型別不匹配而獲得編譯時錯誤。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/373501.html
標籤:打字稿
上一篇:向上箭頭不會變成向下箭頭
