簡體   English   中英

打字稿驗證所有對象值,同時將鍵提取為聯合

[英]Typescript validating all object values while extracting keys as union

我正在嘗試驗證對象文字的值,同時創建所有鍵的聯合作為函數的參數類型。

interface PathValue {
    prop1: string;
    prop2?: number;
}

interface PathDeclaration {
    [key: string]: PathValue;
}

const allPaths: PathDeclaration = {
    'one': {prop1: 'foo'},
    'two': {prop1: 'bar', prop2: 2},
}


function getItem(path: Extract<keyof typeof allPaths, string>) {
    return allPaths[path];
}

此示例的問題在於,由於 PathDeclaration 是 allPaths 的類型,並且其鍵只是通用字符串,因此我的path參數無法再從對象文字中推斷出鍵。

我能想到的唯一解決方案是必須在單獨的界面中聲明所有鍵(重復代碼),或者我可以刪除PathDeclaration並只鍵入每個值,如'one': <PathValue> {prop1: 'foo'},兩者都不是非常優雅的解決方案。 有沒有辦法驗證整個allPaths對象並從對象文字創建一個鍵聯合類型?

您想使用泛型函數初始化const allPaths以 1) 添加類型約束PathDeclaration2) 讓 TS 自動推斷給定的對象文字類型。 只有函數可以一步完成。

const createPaths = <T extends PathDeclaration>(pd: T) => pd

const allPaths = createPaths({
  'one': { prop1: 'foo' },
  'two': { prop1: 'bar', prop2: 2 },
})
/* 
{
  one: { prop1: string; };
  two: { prop1: string; prop2: number; };
}
 */

以上將捕獲錯誤:

const allPathsError = createPaths({
  'one': { prop3: 'foo' }, // error
  'two': { prop1: 'bar', prop2: "bar" }, // error
})

並推斷所有鍵:

// path: "one" | "two"
function getItem(path: Extract<keyof typeof allPathsInline, string>) {
  return allPathsInline[path];
}

這也是我喜歡使用IIFE使事情變得精益的少數情況之一:

const allPathsInline = (<T extends PathDeclaration>(pd: T) => pd)({
  'one': { prop1: 'foo' },
  'two': { prop1: 'bar', prop2: 2 },
})

代碼示例

暫無
暫無

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

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