Home > OS >  Typescript check if type field is optional or not for input required fields
Typescript check if type field is optional or not for input required fields

Time:12-02

I want to check if a typescript type or interface's fields are optional (or not).

export type Recommendation = {
    id?: string,
    name: string,
    type?: string,
    tt: string,
    isin?: string,
    issuer: string,
    quantity?: number,
    recDate: string,
    createDate: string,
    buyPrice?: number,
    currentPrice?: number,
    performance?: number,
    comment?: string,
    updateDate?: string,
    updateRec?: string,
    recentRec?: string,
}

for example name and issuer are not optional, most other fields are.

I now have dynamic input fields (for a submit form) created, and I want to set the "required" attribute on those inputs depending on if the types of the Recommendation type required or not..

        <Table responsive>
            <thead>
                <tr>
                    <th>#</th>
                    <th colSpan={10}>Create new data</th>
                </tr>
            </thead>
        
            <tbody>
                <tr>
                    <td>1</td>
                    {Array.from(Object.keys(sr)).map((colName, index) => (
                        <td key={index}><input required={ checkRequired ? true : false} name={colName} style={{width: "150px"}} type="text" placeholder={JSON.stringify(colName)} onChange={e => setFieldObj(e)} value={inputValue[colName]}></input></td>
                    ))}
                </tr>
            </tbody>
        </Table>
      <button onClick={submitNewRecord}>Submit</button>

how can I do required={ checkRequired ? true : false} with the typescript type?

CodePudding user response:

As @AlekseyL mentioned in the comments, you can't access type information at runtime. But you can, in some cases, access data at compile-time.

If you split your type into a const array of required fields, and a type where none of the fields are optional:

export const RequiredFields = ['name', 'tt', 'issuer', 'recDate', 'createDate'] as const;
type RecommendationFields = {
    id: string,
    name: string,
    type: string,
    tt: string,
    isin: string,
    issuer: string,
    quantity: number,
    recDate: string,
    createDate: string,
    buyPrice: number,
    currentPrice: number,
    performance: number,
    comment: string,
    updateDate: string,
    updateRec: string,
    recentRec: string,
};

You can use that information to reconstruct Recommendation:

type OptionalFields = Exclude<keyof RecommendationFields, typeof RequiredFields[number]>;
type RecommendationOptional = { [key in OptionalFields]?: RecommendationFields[key] };
type RecommendationRequired = { [key in typeof RequiredFields[number]]: RecommendationFields[key] };
export type Recommendation = RecommendationOptional & RecommendationRequired;

And then at runtime you can test if a field is optional by checking that array:

function isFieldRequired(name: string) {
  return RequiredFields.includes(name);
}
  • Related