簡體   English   中英

在TypeScript中使用變量屬性名稱定義對象類型

[英]Define Object type with variable properties name in TypeScript

我在React + TypeScript的“問題”中苦苦掙扎:它實際上並沒有停止我的應用程序,但是現在我想刪除這個疑問!..這更多的是問題!

我要實現的是定義對象的屬性名稱,而屬性名稱由變量給定。 讓我用一個例子來解釋-> https://codepen.io/Gesma94/pen/xmwMzY

/* The 'data' property is "dynamic": it will always have this structure,
 * but the name properties (and the values) may change.
 * The 'mapping' property is used to know the name properties inside 'data'.
 */  
const series = {
  data: [
    {map1: "People reached", map2: 200},
    {map1: "People who called", map2: 117},
    {map1: "Contract signed", map2: 77}
  ],
  mapping: {
    stage: "map1",
    values: "map2"
  }
};

/* This is the actual app. */
const myPar = document.getElementById("myPar");
const { stage: stageLabel, values: valuesLabel} = series.mapping;

series.data.forEach((sample: any, index: number) => {
  myPar.innerHTML = myPar.innerHTML + "<br>" + sample[stageLabel];
});

如您所見,在forEach我編寫了sample: any

現在,我知道sample具有一個string (第一個始終是string )屬性,其名稱為map1 ,這是因為我檢索並保存在stageLabel 我也知道另一個屬性是一個number (始終是一個number ),其名稱map2保存在valueLabel

現在,我渴望了解的是如何不編寫sample: any ,而是使用我之前檢索的信息來定義sample的類型。 基本上,我想編寫如下sample: {stageLabel: string, valueLabel: number}sample: {stageLabel: string, valueLabel: number} ,但是這樣做TypeScript認為sample具有stageLabelvalueLabel屬性,因為我們處於“編譯時”,甚至不能評估變量。

因此,由於TypeScript無法知道變量內部的內容,因此我知道實際上無法獲取sample: {map1: string, map2: number} ,但是也許我可以獲得某種別名。 例如,我編寫了sample: {stageLabel: string, valueLabel: number} ,在其余的代碼中,我使用了sample.stageLabelsample.valueLabel屬性。 然后,在應用程序運行時,將評估那些屬性名稱,因此sample.stageLabel實際上是sample.map1

我希望我已經足夠清楚地理解我的問題。

為什么不實際映射您的數據?

 const series = { data: [ {map1: "People reached", map2: 200}, {map1: "People who called", map2: 117}, {map1: "Contract signed", map2: 77} ], mapping: { stage: "map1", values: "map2" } }; const myPar = document.getElementById("myPar"); let mappedData = getMappedData(series.data, series.mapping); // append results mappedData.forEach((record:{stage:string, value:number}) => { myPar.innerHTML = myPar.innerHTML + `<br>${record.stage}: ${record.value}`; }); function getMappedData(data, mapping): {stage:string, value:number}[] { let stageLabel = mapping["stage"]; let valueLabel = mapping["values"]; return data.map(x => { return { stage: x[stageLabel], value: x[valueLabel] }; }) } 
 <p id="myPar"><b>Results:</b></p> 

請注意,編譯器現在已經知道mappedData中的項目的類型為{stage:string, value:number} ,因此您可以在追加時忽略此內容,只需編寫即可:

// append results
mappedData.forEach(record => {
  myPar.innerHTML = myPar.innerHTML + `<br>${record.stage}: ${record.value}`;
});

暫無
暫無

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

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