網站搜尋

TypeScript - 以類型安全的方式傳遞介面中的欄位名稱


我有:

interface MyInterface {
    a: string;
    b: number;
}

我有另一個通用函數:

myFunction(myInstance: MyInterace, fieldName: string) {
   let field = myInstance[fieldName];

   // do something with this field
}

用法如下:

myFunction(myInst, "a");
or
myFunction(myInst, "b");

不過,我希望以類型安全的方式傳遞「a」或「b」。這意味著如果我將 MyInterface 的一個欄位改成 a2,在 myFunction(myInst, "a") 中的調用將無法編譯,並且我可以在編譯時找到所有因重命名而破壞的地方。

我試過使用 Pick,但無法從中獲取該欄位的名稱。

有什麼建議嗎?我想應該會有一些:

MyInterace::a from which I could extra the string "a".

答案#1

你只需要將 fieldName 宣告為 keyof MyInterface 類型

function myFunction(myInstance: MyInterface, fieldName: keyof MyInterface) {
   let field = myInstance[fieldName];
   // do something with this field
}

myFunction({ a: 'a', b: 1 }, 'a')
myFunction({ a: 'a', b: 1 }, 'b')
myFunction({ a: 'a', b: 1 }, 'c') // type error

遊樂場


或者作為一個更高級的版本,你可以使這個變得通用,然後它將可以與任何類型一起使用,而不僅僅是 MyInterface。

現在你可以將任何類型傳給 myInstance,而 fieldName 必須是該類型的 keyof。

function myFunctionGeneric<T>(myInstance: T, fieldName: keyof T) {
  let field = myInstance[fieldName];
  // do something with this field
}

myFunctionGeneric({ foo: 'a', bar: 1 }, 'foo')
myFunctionGeneric({ foo: 'a', bar: 1 }, 'bing') // type error

當然,只有在需要時才使用這個通用版本,因為它會引入一些你可能根本不需要的複雜性。

遊樂場