Ramon Balthazar
Ramon Balthazar

Reputation: 4270

How to constraint an object's keys but infer values as const?

Given this object, is there a way to infer its values as const while ensuring the keys are contained in the Field union?

type Field = 'name' | 'isHappy';

const fieldTypes: { [field in Field]: string } = {
  name: 'text',
  isHappy: 'checkbox',
};

My goal is so that fieldTypes has the type:

{
  name: 'text';
  isHappy: 'checkbox';
}

instead of

{
  name: string;
  isHappy: string;
}

Upvotes: 2

Views: 244

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 250036

Not just a variable declaration. Variable types are either inferred from the value assigned or are specified by a type annotation, there is no middle ground.

You can instead use a function, which can have a type both inferred and constrained:

type Field = 'name' | 'isHappy';

function createFields<T extends Record<Field, V>, V extends string>(o: T) {
  return o;
}

const fieldTypes = createFields({
  name: 'text',
  isHappy: 'checkbox',
})

// Typed as: 
// const fieldTypes: {
//     name: "text";
//     isHappy: "checkbox";
// }

Playground Link

Upvotes: 2

Related Questions