1

I have a interface for typing that looks like the following

interface Bob{
    a: number;
    b: number;
    c: number;
}

However, I don't really want number as any number can be valid. How can I enforce the type of Bob to be numbers strictly in a JSON file like the following.

{
  "None": -1,
  "foo": 22,
  "moo": 55,
  "raar": 13,
  "zaar": 2,
  "bar": 0,
  "fooboo": 22,
  "mooboo": 1000,
}

That JSON contains around 200 entries hence doing a manual typedef is not optimal.

What I aim to achieve

const myvar: Bob;
myvar.a = 2222 // this should throw an error as this number is not defined in the JSON
myvar.b = -1 //this is ok as it is in the JSON

Thanks!

6
  • 1
    Import json (it will be typed), then do type values = typeof v[keyof typeof v]; (where v is your imported json) Commented Jan 17, 2021 at 23:02
  • wont work. You still can user other numbers -> typescriptlang.org/play?#code/… Commented Jan 17, 2021 at 23:16
  • 2
    @MartinGodzina will work, if you type it as const typescriptlang.org/play?#code/… Commented Jan 17, 2021 at 23:20
  • Thank you @zerkms! Works like a charm. Do you mind explaining what does the as const do at the end? Commented Jan 17, 2021 at 23:33
  • @DingMa typescriptlang.org/docs/handbook/release-notes/… Commented Jan 17, 2021 at 23:33

1 Answer 1

3

Thanks to @zerkms for the answer.

const json = {
  "None": -1,
  "foo": 22,
  "moo": 55,
  "raar": 13,
  "zaar": 2,
  "bar": 0,
  "fooboo": 22,
  "mooboo": 1000,
} as const;

type $Values<T extends object> = T[keyof T];
type supportedNumbers = typeof json[keyof typeof json];

interface Bob{
    a: supportedNumbers;
    b: supportedNumbers;
    c: supportedNumbers;
}

const NiceBob: Bob = {
  a: 3909, //error
  b: 319039, //error
  c: -1 //no error
};

Example can be found here

Docs can be found here

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

3 Comments

Do you need to refer to the const json at runtime? Or do you only define it to define the type supportedNumbers? If it is the latter: You could go without having a const by using type json = { ... } and type supportedNumbers = json[keyof json].
in my case const is good since it is loaded when the app is running and will not be modified

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.