0

I have list of properties that should be as a keys of interfaces with different types. How better to implement them? I want not to allowed to use properties that not exist in enum.

export enum SomePropetries {
  prop1,
  prop2,
  prop3
};

export interface PropsInterface {
  [SomePropetries.prop1]: number;
  [SomePropetries.prop2]: boolean;
  [SomePropetries.prop3]: string;
}


// Usage example. 
// I have object of properties. Each of property can be updated separatelly.

let props: PropsInterface = {
   [SomePropetries.prop1]: null,
   [SomePropetries.prop2]: null,
   [SomePropetries.prop3]: null
};

const fieldToUpdate: {
  field: SomePropetries;
   value: number;
} = {
   field: SomePropetries.prop1,
   value: 123
};

props[fieldToUpdate.field] = fieldToUpdate.value;
4
  • please provide reproducible example, your exmaples contains a syntax errors Commented Oct 19, 2021 at 12:07
  • Please check. Now no syntax errors. Commented Oct 19, 2021 at 13:33
  • let fieldToUpdate { and field: Properties = Properties.prop1, is not valid syntax Commented Oct 19, 2021 at 13:36
  • 1
    Now I fixed a lot. Please check. I only have a n error: Type 'number' is not assignable to type 'never'. But this is my problem Commented Oct 19, 2021 at 13:38

1 Answer 1

1

First of all, you need to make PropsInterface all properties nullable.

export enum SomePropetries {
  prop1,
  prop2,
  prop3
};

interface PropsBase {
  [SomePropetries.prop1]: number;
  [SomePropetries.prop2]: boolean;
  [SomePropetries.prop3]: string;
}

type NullableRecord<T> = {
  [Prop in keyof T]: T[Prop] | null
}

type PropsInterface = NullableRecord<PropsBase>

Then, you are allowed to use null as a property type.

let props: PropsInterface = {
  [SomePropetries.prop1]: null,
  [SomePropetries.prop2]: null,
  [SomePropetries.prop3]: null
}

This does not work,

const fieldToUpdate = {
  field: SomePropetries.prop1,
  value: 123
}

props[fieldToUpdate.field] = fieldToUpdate.value;

because fieldToUpdate.field is infered as enum. I mean it expect all possible enum keys, whereas you are interested in only one SomePropetries.prop1.

Hence, in order to make it work, you should just use as const assertion.

const fieldToUpdate = {
  field: SomePropetries.prop1,
  value: 123
} as const

props[fieldToUpdate.field] = fieldToUpdate.value;

Whole code:

export enum SomePropetries {
  prop1,
  prop2,
  prop3
};

interface PropsBase {
  [SomePropetries.prop1]: number;
  [SomePropetries.prop2]: boolean;
  [SomePropetries.prop3]: string;
}

type NullableRecord<T> = {
  [Prop in keyof T]: T[Prop] | null
}

type PropsInterface = NullableRecord<PropsBase>


// Usage exanple. 
// I have object of properties. Each of property can be updated separatelly.

let props: PropsInterface = {
  [SomePropetries.prop1]: null,
  [SomePropetries.prop2]: null,
  [SomePropetries.prop3]: null
};

const fieldToUpdate = {
  field: SomePropetries.prop1,
  value: 123
} as const

props[fieldToUpdate.field] = fieldToUpdate.value;

Playground

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

4 Comments

Thank you! But how to make exact types?
What do you mean exact? Could you please provide an example?
I edited my example. Please have a look.
Now works good! Thank you so much. Here is some magic with nullableRecord. I have to learn about it ))

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.