1
const supported = ["a", "b", "c"];
const someObject = {a: 2, b: 3}; // I want TS to throw: error, has no 'c'!

I've got a const array of strings. How do I assert that an object's keys cover all the values?

5
  • What should happen for const someObject = {a: 2, b: 3, c: undefined};? Commented Oct 26, 2020 at 9:55
  • You could do: const allKeysExist = supported.forEach(key => someObject.hasOwnProperty(key)); // true or false Commented Oct 26, 2020 at 10:01
  • @mjwills I'll be happy with either solution. Commented Oct 26, 2020 at 10:04
  • @Joel I'm looking for a pure TS solution. Commented Oct 26, 2020 at 10:04
  • @zerkms Perfect, thank you. Please post this as a solution, so I can accept it. And out of pure curiosity, is it doable without helper types? Commented Oct 26, 2020 at 10:06

1 Answer 1

3

You could do

const supported = ["a", "b", "c"] as const;

const someObject: Record<typeof supported[number], number> = {a: 2, b: 3};

It enforces all values to be numbers and the object to have all the keys from supported.

You surely can relax the type of the values to be unknown or any.

If you for some reason don't want to use the built-in Record<K, V> type you can always expand it to { [P in typeof supported[number]]: number }.

Important note: the supported value must be known compile time.

Playground: https://www.typescriptlang.org/play?ssl=1&ssc=38&pln=1&pc=43#code/MYewdgzgLgBBCuAHRIBOUCmATGBeGA2gEQCGRANDEQEYVXBEC6MJEMokUA3ALABQ-DtDggAthgDy1AFYZgUAFwwASnLRYAPFACeiDCABmcJCnTYCYeKOoZUjSpeu2AfHhgBvEkoBMlakoBmAF8uGAB6MJgASRgAdxIwWAAVAGUYKBB0gAtUEFilW1zUSizWGDBMgHJgSoBCIA

Update:

a solution to have some keys optional:

const supported = ["a", "b", "c", "d", "e"] as const;

type Keys = typeof supported[number];
type OptionalKeys = "d" | "e";
type MandatoryKeys = Exclude<Keys, OptionalKeys>

const someObject: Record<MandatoryKeys, number> & Partial<Record<OptionalKeys, number>>  = {a: 2, b: 3, c: 42};

https://www.typescriptlang.org/play?#code/MYewdgzgLgBBCuAHRIBOUCmATGBeGA2gEQCGRANDEQEYVXB1FaMZEC6MJEMokUA3AFgAUCKgBPRBhgBpDOO74JUkADM4SFOmwEw8ALbUMqNkOHLpAeURQAluBIAbOQrxVmMAD5VWZizABZEjAsEig0cRdFGABRAA9gR3gsDAAeKMprOwdneQgAPhERXmg4EH0MS2oAKwxgKAAuGAAlOrQsVKCQsIiMmD1DY3yYADIYAAUSdFsnVNbQVA6s+zAnPoGjVHzhtwBvEiaAJkpqJoBmSmAmgBZDgF9+IA

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

1 Comment

What if I wanted all of the keys be present in the array, but not the entire array should be covered? I.e. adding d would throw, but not adding c is fine.

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.