Yu Miao
Yu Miao

Reputation: 572

Typescript type detection not working using object

interface IConfig1 {
    name: string,
    age: string
}

interface IConfig2 {
    name: string
}

const config1: IConfig1 = {
    name: "123",
    age: "123"
}

var config2: IConfig2 = {
    // Type '{ age: string; name: string; }' is not assignable to type 'IConfig2'.
    // Object literal may only specify known properties, and 'age' does not exist in type 'IConfig2'.(2322)
    age: "123", 
    name: "123"
}

// Why no error 
var config3: IConfig2 = config1

playground

Defining the config2 object throws an error because the age does not exist in type IConfig2. But what confuses me is why config3 don't throw the error 'age' does not exist in type 'IConfig2'.

How to fix it? make config3 throw the error.

Upvotes: 0

Views: 55

Answers (1)

It is called excess-property-checks

Object literals get special treatment and undergo excess property checking when assigning them to other variables, or passing them as arguments.

In your second example:

var config3: IConfig2 = config1

you are using object reference instead of literal, that's why excess property checking is disabled

UPDATE

// Type for function arguments
type Strict<A, B> = keyof A extends keyof B ? keyof B extends keyof A ? A : never : never

const strict = <T, U extends Strict<T, IConfig2>>(arg: T, ...validation: T extends U ? [] : [never]) => arg
const x = strict(config2) // ok
const y = strict(config1) // expected error

Please keep in mind, Strict type just checks first level of properties. If your config object has nested properties it will not work

Upvotes: 1

Related Questions