Search code examples
typescripttypeskeyof

Type which matches any value of a constant object


Given this const:

const beatsByDuration = {
    q: 1,
    h: 2,
    w: 4,
    1: 4 / 1,
    2: 4 / 2,
    4: 4 / 4,
    8: 4 / 8,
    16: 4 / 16,
};

These types are equivalent.

type Duration = 'q' | 'h' | 'w' | '1' | '2' | '4' | '8' | '16';
type Duration = keyof typeof beatsByDuration

How can I define a type which matches any of the values of the object (1 | 2 | 4 | 0.5 | 0.25) ?

(I see several similar-ish questions, but none exactly like this. I don't want to just match the types of the values, but the values themselves. And my object is not a type, it's an object.)


Solution

  • It's possible with a const-assertion if you defined your values as literal values instead of expressions. E.g. 4 / 16 is simply inferred as number since the actual value (0.25) is determined at runtime.

    const beatsByDuration = {
        q: 1,
        h: 2,
        w: 4,
        1: 4,
        2: 2,
        4: 1,
        8: 0.5,
        16: 0.25,
    } as const;
    
    type Values = typeof beatsByDuration[keyof typeof beatsByDuration];
    // type Values = 1 | 2 | 4 | 0.5 | 0.25
    

    TypeScript Playground