amwill04
amwill04

Reputation: 1360

Typescript generic callback object strictness

Im struggling to understand why the following doesnt throw an error

type Callback<T> = () => T

function format<V>(callback: Callback<V>): V {
    return callback()
}

type Test = {foo: string}

format<Test>(() => {
    return {
        foo: 'hello',
        bar: 'dd' // I expect an error to be here as `bar` does not exist on type Test
    }
})

// if I explicitly set the return type in the callback then I get the correct error

format<Test>((): Test => {
    return {
        foo: 'hello',
        bar: 'dd' // this now errors as I have set the return type.
    }
})

I cant help but feel this is a duplication?

Is this a typescript limitation and is "as expected", or are my types incorrect?

Upvotes: 4

Views: 58

Answers (1)

Aleksey L.
Aleksey L.

Reputation: 37986

Excess property checking is not triggered because callback doesn't have explicit type notation. Typescript infers its type as () => { foo: string; bar: string } which is assignable to Callback<Test>.

Have a look at this example:

type Callback<T> = () => T

type Test = { foo: string }

const extendedCallback = () => ({ foo: 'hello', bar: 'bar' }) // inferred as () => { foo: string; bar: string }

const callback: Callback<Test> = extendedCallback // assignment is valid

Playground

Upvotes: 1

Related Questions