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

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

鍵入一個接受數組的函數,更改其屬性之一,但仍返回相同類型的數組

鍵入一個接受數組的函數,更改其屬性之一,但仍返回相同類型的數組

守候你守候我 2023-02-24 10:38:18
我將表單字段表示為對象,這些對象被映射并基于type返回的 React 元素:import { FieldProps } from "~types";const fields: FieldProps[] = [  { type: "text", name: "username", value: "", required: true, ...other props },  { type: "password", name: "password", value: "", required: true, ...other props },  ...etc]export default fields;我遇到的問題是我試圖在提交表單后驗證字段并檢查是否有任何錯誤value: handleSubmit = (e: FormEvent<HTMLFormElement>) => {    e.preventDefault();    const { validatedFields, errors } = fieldValidator(this.state.fields);    if(errors) {      this.setState({ errors });      return;    }    ...etc }但是這個可重用的驗證函數有一個 ts 錯誤:import isEmpty from "lodash.isempty";/** * Helper function to validate form fields. * * @function * @param {array} fields - an array containing form fields. * @returns {object} validated/updated fields and number of errors. * @throws {error} */const fieldValidator = < T extends Array<{ type: string; value: string; required?: boolean }>>(  fields: T,): { validatedFields: T; errors: number } => {  try {    if (isEmpty(fields)) throw new Error("You must supply an array of form fields to validate!");    let errorCount: number = 0;    // this turns the "validatedFields" array into an { errors: string; type: string; name:     // string; value: string; required?: boolean | undefined;}[] type, when it needs to be "T",     // but "T" won't be inferred as an Array with Object props: type, value, required, value defined within it    const validatedFields = fields.map(field => {      let errors = "";      const { type, value, required } = field;      if ((!value && required) || (isEmpty(value) && required)) {        errors = "Required.";      } else if (        type === "email" &&        !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(field.value)      ) {        errors = "Invalid email.";      }      if (errors) errorCount += 1;      return { ...field, errors };    });有沒有一種方法可以推斷T為至少需要 4 個(或更多)屬性的對象數組,但返回相同類型的數組(僅具有更新的errors屬性)?
查看完整描述

2 回答

?
當年話下

TA貢獻1890條經驗 獲得超9個贊

我設法通過擴展T到然后定義保留傳入類型any[]的結果來弄清楚:validatedFields as T


const fieldValidator = <

  T extends any[]

>(

  fields: T,

): { validatedFields: T; errors: number } => {

  try {

    if (!fields || fields.length < 0) throw new Error("You must supply an array of fields!");

    let errorCount: number = 0;


    const validatedFields = fields.map(field => {

      let errors = "";

      const { type, value, required }: Pick<BaseFieldProps, "type" | "value" | "required"> = field;

      if ((!value && required) || ((value && value.length < 0) && required)) {

        errors = "Required.";

      } else if (

        type === "email" &&

        !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)

      ) {

        errors = "Invalid email.";

      } 


      if (errors) errorCount += 1;


      return { ...field, errors };

    }) as T;


    return { validatedFields, errors: errorCount };

  } catch (err) {

    throw String(err);

  }

};


查看完整回答
反對 回復 2023-02-24
?
DIEA

TA貢獻1820條經驗 獲得超2個贊

這是你要找的嗎?


type EssentialField = { type: string; value: string; required?: boolean }[];

打字稿使用鴨子打字。


type FieldProps = {

  className?: string,

  disabled?: boolean,

  errors?: string,

  placeholder?: string,

  label: string,

  // onChange?: (e: React.ChangeEvent<any>) => void;

  name: string,

  type: string,

  readOnly?: boolean,

  required: boolean,

  value: string

  styles?: object

};



const fields: FieldProps[] = [

  { 

    type: "text", 

    label: "Username", 

    name: "username", 

    errors: "",

    value: "", 

    required: true,

  },

  { 

    className: "example",

    type: "password", 

    label:"Passowrd", 

    name: "password", 

    errors: "", 

    value: "", 

    required: true, 

    styles: { width: "150px" },

  }

];


type EssentialField = { type: string; value: string; required?: boolean }[];


const fieldValidator = (

  fields: EssentialField,

): { validatedFields: EssentialField; errors: number } => {

  try {

    if (!fields || fields.length < 0) throw new Error("You must supply an array of fields!");

    let errorCount: number = 0;


    const validatedFields = fields.map(field => {

      let errors = "";

      const { type, value, required } = field;

      if ((!value && required) || ((value && value.length < 0) && required)) {

        errors = "Required.";

      } else if (

        type === "email" &&

        !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(field.value)

      ) {

        errors = "Invalid email.";

      }


      if (errors) errorCount += 1;


      return { ...field, errors };

    });


    return { validatedFields, errors: errorCount };

  } catch (err) {

    throw String(err);

  }

};


const { validatedFields, errors } = fieldValidator(fields)

console.log(validatedFields)

console.log(errors);

這消除了錯誤,沒有使用as any或其他技巧。


編輯:也許你想要這樣的東西:


type EssentialField = ({ type: string; value: string; required?: boolean }&{[key: string]: any})[];


// this allow you to do:

validatedFields[0].placeholder; // ...

// or

validatedFields[0].someUnknowProperty; // ...

這是將類型與關聯數組 ( {[key: string]: any})) 相交。通常這樣訪問associativeArray['someKey'],但也可以這樣使用associativeArray.someKey。


好處是您的 IDE 應該在自動完成中為您推薦type和字段。required


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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