0

I have the following interface:

export interface IFormField {
    /** Field name */
    name: string;

    /** Label to appear on form */
    label?: string;   // this is optional, since hidden fields do not have label

    /** Field type */
    type: 'accordion' | 'address' | 'camera' | 'category_box' | 'category_list';
}

and I'd like to extend the valid values of type picking them by an object like this one:

const arr = {
   'new_type1': 1,
   'new_type2': 2,
   'new_type3': 3,
};

How do I add new_type1, new_type2 and new_type3 to the list of valid names in the type field?

As a result, I'd like to have:

type: 'accordion' | 'address' | 'camera' | 'category_box' | 'category_list' | `new_type1` | `new_type2` | `new_type3`;

For another complete (not working) example:

const arr: any = {
   'new_type1': 1,
   'new_type2': 2,
   'new_type3': 3,
};

export interface IFormField {
    /** Field name */
    name: string;

    /** Label to appear on form */
    label?: string;   // this is optional, since hidden fields do not have label

    /** Field type */
    type: keyof typeof arr;
}

const f: IFormField = {
    name: 'ciao',
    type: "new_type1"
};

// adding a new key to `arr` at runtime
arr.type4 = 4;

const g: IFormField = {
    name: 'cioa',
    type: 'type4'  // <- valid for IFormField.type ?
}

Is it possible?

Thanks

2 Answers 2

2

It is easy to construct the desired type:

  • capture the new keys in type NewFieldTypes
  • make an union of old types and new types
  • lastly, substitute the type field in IFormField
export interface IFormField {
    /** Field name */
    name: string;

    /** Label to appear on form */
    label?: string;   // this is optional, since hidden fields do not have label

    /** Field type */
    type: 'accordion' | 'address' | 'camera' | 'category_box' | 'category_list';
}

const arr = {
   'new_type1': 1,
   'new_type2': 2,
   'new_type3': 3,
};

type NewFieldTypes = keyof typeof arr;
type ExpandedFieldTypes = IFormField['type'] | NewFieldTypes

type ExpandedIFormField = Omit<IFormField, "type"> & {
  type: ExpandedFieldTypes
};

Playground

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I have updated the question because my starting arr is not a type, but a key / values object and I need to change its values at runtime, yet having the type check while coding.
The compiler has no way of knowing what you add to the array at runtime (could be user-provided input) so it cannot enforce it. The best you can do is to allow any string.
0
type MyCombinedUnion = keyof typeof arr | IFormField["type"]

https://www.typescriptlang.org/play?ts=4.3.5&ssl=19&ssc=6&pln=19&pc=21#code/FAUwHgDg9gTgLgAgJYDs4hgMwIYGMQICSAYrALbFIgA2AJggN7AIsID0AVBwpTfStjIEObZqwFCAXAgDOcGKgDmAbmBiWnbgBlsAIxoI4UBNggQQ2GAigoEmcghHqE1PTQD80uQpQrWbNkMACyQZZDCoCDgkG2xqABpZVHwEENpaEFtMKjow2mMUKEQg7AA3Ald9ajVWdi4eHPo4AE9zR1FalvNpAHI8XFhaGJQehAAfBD70mBAZGVGJntxBDGwFyeX0RVhmgH1dKDB1pewtnd3qULge1QBfNQGUORMYKwBeRnUelBAAd12uiAAIw9aRA+JfH7-QEAJlBCBhENY3z+ANaIAAzPCMRDbqpgICEABZZoAYSgZF0qBAtAAqihhggPgBrEDNKCYQzojkvKwTEjkXh0ADaACJAaKALpAA

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.