簡體   English   中英

如何在 typescript 中提供自動代碼完成的同時將數組縮減為 object?

[英]How to reduce an array to object while providing auto code completion in typescript?

最近我正在嘗試 typescript 並且在深入研究它時我被困在一個我無法前進的地方。 所以我有一個字符串數組,我想將它縮減為 object,同時獲得所有正確的提示和代碼完成。 雖然我已經到達 typescript 沒有拋出任何錯誤的地方,但我仍然無法實現代碼完成行為。 在這里粘貼示例代碼以供參考。

interface GetObjI {
  [key: string]: string;
}

function getObj(myArray: string[]): GetObjI {
  return myArray.reduce((prev, curr) => {
    prev[curr] = curr;
    return prev;
  }, {});
}

const arr = ["name", "age"];

const obj = getObj(arr);

console.log(obj.age); // Here I wasn't able to achieve code completion.

使用嚴格的 TypeScript 設置,您的代碼應該會拋出錯誤。

prev[curr] = curr;

投擲

元素隱式具有“任何”類型,因為類型“字符串”的表達式不能用於索引類型“{}”。

在類型“{}”上找不到參數類型為“字符串”的索引簽名。(7053)

這是有道理的——當你傳入它時,你沒有為累加器提供任何特殊類型,所以分配給它的一個屬性不會與其現有類型(作為一個空對象)相匹配。

使用通用類型參數來指示累加器的類型,並使getObj也通用,以便可以傳遞myArray中的值(而不是僅使用string[] ,后者過於通用)。

您還需要鍵入as const傳入的數組,這樣它就不會在 function 調用之前擴展為string[]

function getObj<T extends readonly string[]>(myArray: T) {
    // Type out the type of the full object with all properties here to be DRY
    type Accum = Record<T[number], T[number]>;
    // The object doesn't have all properties inside the callback, though
    // so we need to use Partial to indicate that some or all can be missing
    return myArray.reduce<Partial<Accum>>((prev, curr: T[number]) => {
        prev[curr] = curr;
        return prev;
    }, {}) as Accum; // When returning, indicate that it's no longer Partial, but has all properties
}

const arr = ["name", "age"] as const;

const obj = getObj(arr);

console.log(obj.age);

但是.reduce不是這種情況下的正確工具- 它需要冗長的 TypeScript 輸入,即使在標准 JavaScript 中也不是一個好主意,因為累加器保持不變 object。只需使用循環即可。

function getObj<T extends readonly string[]>(myArray: T) {
    const obj: Record<string, string> = {};
    for (const prop of myArray) {
        obj[prop] = prop;
    }
    return obj as Record<T[number], T[number]>;
}

或者使用Object.fromEntries

const getObj = <T extends readonly string[]>(myArray: T) =>
    Object.fromEntries(myArray.map(prop => [prop, prop])) as Record<T[number], T[number]>;

不幸的是,所有這些方法都需要幫助 TS 以及一些類型斷言。 使用循環或reduce需要在循環內將屬性鍵入為可選,但在循環外需要 - 而Object.fromEntries僅給出一種Record<string, T>作為響應,這不夠具體。

暫無
暫無

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

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