wisha
wisha

Reputation: 713

Force TypeScript to type object literally

I have a large constant JavaScript object. Something like this:

const commonStyles = {
    fullContainer: {
        flex: 1,
        alignItems: 'stretch',
        justifyContent: 'flex-start',
    },
    justifyEvenly: {
        justifyContent: 'space-evenly',
    },
    widthBound: {
        width: '100%',
        maxWidth: breakpoints.default,
        alignSelf: 'center',
    }
    (...there is more)
}

TypeScript automatically types all the CSS property texts ("flex-start", "space-evenly", etc.) as string, but I want them to be typed as literals.

// What I get
{
    fullContainer: {
        flex: number,
        alignItems: string,
        justifyContent: string,
    },
    ...
}
// What I want
{
    fullContainer: {
        flex: number,
        alignItems: 'stretch',
        justifyContent: 'flex-start',
    },
    ...
}

I could manually annotate the type, of course. But the object here is very large (>50 entries and growing), so writing the complete type annotation would be very tedious.

My question: is there a way to make TypeScript automatically type the object as literally as possible?

Upvotes: 0

Views: 355

Answers (1)

Aleksey L.
Aleksey L.

Reputation: 37928

const assertion can be used to prevent literal types widening:

const commonStyles = {
    fullContainer: {
        flex: 1,
        alignItems: 'stretch',
        justifyContent: 'flex-start',
    },
    justifyEvenly: {
        justifyContent: 'space-evenly',
    },
    //...
} as const;

Playground

  • no literal types widened
  • object literals get readonly properties
  • array literals become readonly tuples

Upvotes: 1

Related Questions