亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何使用動態對象數組中的鍵動態鍵入對象

如何使用動態對象數組中的鍵動態鍵入對象

精慕HU 2023-02-24 10:44:58
我有一個函數可以減少屬性數組并構建一個對象:type FieldProps = {  name: string;  value: string;  required: boolean;  styles?: object;  className?: string}const fields: FieldProps[] = [  {    name: "firstName",    value: "Bob",    required: true,    styles: { width: "100%"}  },  {    name: "lastName",    value: "Smith",    required: true,    className: "example"  },  {    name: "city",    value: "Tulsa",    required: true,  },  {    name: "state",    value: "OK",    required: true,  },]const parseFields = <T extends any[], K extends object = {}>(fields: T): K => {  try {    if (!fields || (fields && fields.length < 0)) throw new Error("You must supply an array of fields!");    const parsedFields = fields.reduce((acc, { name, value }: { name: string, value: string}) => {      switch (name) {        case "city":        case "street":        case "state":        case "suite":        case "zipCode": {          acc["address"] = acc["address"] || {};          if (value) acc.address[name] = value;          break;        }        default: {          acc[name] = value;          break;        }      }      return acc;    }, {} as K);    return parsedFields;  } catch (err) {    throw String(err);  }};const userDetails = parseFields(fields);截至目前,懸停在上方userDetails會顯示一個空對象類型( {}),理想情況下應該是:{  "firstName": string,  "lastName": string,  "address": {    "city": string,    "state": string  }}我如何重構函數以獲取類型FieldProps[]并讓它返回動態類型的對象?
查看完整描述

3 回答

?
有只小跳蛙

TA貢獻1824條經驗 獲得超8個贊

這個答案非常(過度)復雜,但你最終會得到這種類型:


const userDetails = parseFields(fields);

type Z = typeof userDetails;

// type Z = {

//     address: {

//         city: "Tulsa" | "Norman"; // Added to test

//         state: "OK";

//     };

// } & {

//     firstName: "Bob";

//     lastName: "Smith";

// }

它需要制作fields as const:


const fields = [

  ...

] as const;

還有……實際的打字:


type AddressKeys = 'city' | 'street' | 'state' | 'suite' | 'zipCode';


type _ParseFieldsResultKeys<T extends readonly FieldProps[]> = {

  [K in keyof T]: T[K] extends { name: string } ? T[K]['name'] : never;

}[Exclude<keyof T, keyof []>];


type _GetParseFieldResultValue<T extends readonly FieldProps[], N> =

  Extract<T[keyof T], { name: N }> extends { value: infer V } ? V : never;


type ParseFieldsResult<T extends readonly FieldProps[]> = {

  address: {

    [N in Extract<_ParseFieldsResultKeys<T>, AddressKeys>]: _GetParseFieldResultValue<T, N>;

  }

} & {

  [N in Exclude<_ParseFieldsResultKeys<T>, AddressKeys>]: _GetParseFieldResultValue<T, N>;

};


const parseFields = <T extends readonly FieldProps[]>(fields: T): ParseFieldsResult<T> => {

使用它可能不是一個好主意。但是:游樂場鏈接


編輯:意識到我們不需要實際的字符串文字類型,只需要string我們可以擺脫_GetParseFieldResultValue并仍然得到的值:


type Z = {

    address: {

        city: string;

        state: string;

    };

} & {

    firstName: string;

    lastName: string;

}


查看完整回答
反對 回復 2023-02-24
?
長風秋雁

TA貢獻1757條經驗 獲得超7個贊

在 parseFields 函數中,你有一個 K.. 的返回類型,它是一個空對象......你不應該傳入 FieldProps 嗎?

const parseFields = <T extends any[], K extends object = {}>(fields: T): **FieldProps** => {


查看完整回答
反對 回復 2023-02-24
?
智慧大石

TA貢獻1946條經驗 獲得超3個贊

您在此處使用通用方法,并將 K 的默認類型設置為 {},這就是您在懸停時看到 {} 的原因。


您可以通過正確調用該方法來實現您正在尋找的東西。像這樣:


const userDetails = parseFields<FieldProps[], {

  "firstName": string,

  "lastName": string,

  "address": {

    "city": string,

    "state": string

  }

}>(fields);  


查看完整回答
反對 回復 2023-02-24
  • 3 回答
  • 0 關注
  • 153 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號