Search code examples
typescript

Why an empty object can the type asserted to anything?


Seems like it shouldn't be allowed...

let wow = {} as boolean //No errors O.O
let wow2 = {} as [] //No errors O.O
let wow3 = {} as Function //No errors O.O
let wow4 = {} as number //No errors O.O
let wow5 = {} as string //No errors O.O
let wow6 = {} as symbol //No errors O.O

Solution

  • The empty object type is a little weird at first.

    So, first, typescript is structural. This means that {} describes a type that requires zero properties. Therefore, pretty much anything is assignable to {} because almost every type can fulfill the structural type contract that is having all zero of the required properties.


    Second, as is inherently not type safe.

    declare const strOrNull: string | null
    
    const str: string = strOrNull as string // TS says fine, but really it might be null!
    str.split(' ') // TS says fine, but maybe a crash
    

    A type assertion using as tells Typescript that you know better than the compiler does, and you want to narrow the type that the compiler is using to something more specific that only you know it can be.

    So given that that boolean is assignable to {} due to the first point above, it allows the type assertion.


    Important lesson: Don't use as unless you are sure you are right.