Search code examples
typescripttypestypeerrorduck-typing

Typescript: Assign object Literal to typed variable / typeof object literal. Both possible?


Given an type:

type MyType = {
   A: number | string
}

the following will raise an error (exactly as I want it):

const myValue1: MyType = {
   A: 123,
   B: "Oh!", // raises a type error, because I accidentally defined the property B
}

On the other hand, the following would give me the type of the object literal:

const myValue2 = {
   A: 123
}
const MyLiteralType = typeof myValue2; // {A: number}

Ideally I want to have both:

  • strict checking when assigning to myValue (no additional properties allowed), and
  • extracting the type of myValue as I defined it as ab object literal ({A: number})

Can I trick typescript to give me that, without having to explicitely to define a second type ({A: number}) ? A am out of ideas.

It seems I can only have one or the other:

  • either assign an object literal to a typed variable and have strict type checking, or
  • extract the type of the object literal, but no strict type checking (only duck typing).

May be I can, through some template magic, compare the two types (MyType and MyLiteralType) and raise an error when there are additional properties ?


Solution

  • This is exactly what the satisfies operator was made for:

    type MyType = {
       A: number | string
    };
    const myValue2 = {
       A: 123
    } satisfies MyType;
    const myValue1 = {
       A: 123,
       B: "Oh!", // raises a type error, because I accidentally defined the property B
    } satisfies MyType;
    type MyLiteralType = typeof myValue2; // {A: number}
    

    (online demo)