Home > OS >  Typescript create key constrained type for object literal with inferred number values
Typescript create key constrained type for object literal with inferred number values

Time:11-18

Let's say we have object literal like:

export const SOURCE = {
    UNKNOWN: 'Unknown',
    WEB: 'Web',
    MOBILE: 'Mobile',
    ...
} as const;

and

export const OTHER_SOURCE = {
    UNKNOWN: 0,
    WEB: 1,
    MOBILE: 2, // values might be not sequential or incrementing at all 
    ...
} as const;
OTHER_SOURCE.UNKNOWN // inferred to 0  

How to constrain second object literal so it has keys from SOURCE but the values are still inferred as literals, not numbers like below:

type ConstraintType = {
    [key in keyof typeof USER_SOURCE]: number; // how to infer (and possibly still force numbers) numeric values from the second object?
};
export const OTHER_SOURCE: ConstraintType = { ... } as const;
OTHER_SOURCE.UNKNOWN // inferred to number ]  

Thank you for help and clarifications.

CodePudding user response:

If you specify the type of a variable, that is it's final type, so as long as the expression on the right is assignable to it, everything is fine.

If you want to capture capture the types from the object literal assigned to OTHER_SOURCE but also constrain it to have the same properties, you can use a function

export const SOURCE = {
    UNKNOWN: 'Unknown',
    WEB: 'Web',
    MOBILE: 'Mobile',
} as const;

function makeSource<T extends Record<keyof typeof SOURCE, V>, V extends number>(o: T): Readonly<T> {
  return o
}
const OTHER_SOURCE = makeSource( {
    UNKNOWN: 0,
    WEB: 1,
    MOBILE: 2, // values might be not sequential or incrementing at all  
});


OTHER_SOURCE.UNKNOWN // 1

Playground Link

  • Related