Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Why does Object.entries return a union type?

I’m using the following code, with typescript 4.7.3, and don’t understand why the type of amount isn’t PositiveNumber.

export type PositiveNumber = number & { __type: 'PositiveNumber' }
export type PointsByAbbrev = Record<string, PositiveNumber> & { __type: 'PointsByAbbrev' }
export const isPointsByAbbrev = (value: Record<string, number> | null | undefined): value is PointsByAbbrev => hasValue(value) && Object.values(value).every(x => x >= 0)

class Foo {
    data!: PointsByAbbrev
    
    generate(input: Record<string, number>) {
        if (isPointsByAbbrev(input))
            this.data = input
    }

    someMethod(): void {
        Object.entries(this.data).forEach(([abbrev, amount]) => {
        })
    }
}

According to the compiler, the type of amount is PositiveNumber | "PointsByAbbrev"

I’m assigning the data via a process like the generate method shows where I pass the input through the type guard and then assign if true.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

It looks like you’re trying to do some variety of newtype pattern with that __type field, but that doesn’t make the field any less real. As far as Typescript is concerned, __type is a valid slot on your object and its type is 'PointsByAbbrev'. The type of this.data is

Record<string, PositiveNumber> & { __type: 'PointsByAbbrev' }

The fields of Record<string, PositiveNumber> have type PositiveNumber, and the fields of { __type: 'PointsByAbbrev' } have type 'PointsByAbbrev', so the entire intersection type’s fields have type PositiveNumber | 'PointsByAbbrev'

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading