Skip to content

Bug with type argument inference if it has default value = undefined and actual value is object with non-arrow function #62995

@termi

Description

@termi

There is a difference in how TypeScript infers the type automatically based on type of the argument we pass in:

  • how the value is declared (inline or by reference)
  • whether the value is an inline object with non-arrow function

The error is reproduced if generic parameter has default value undefined (this is mandatory in my case.)

🔎 Search Terms

  • "generics in constructor"
  • "type argument inference undefined"

🕗 Version & Regression Information

  • This is the behavior in every version I tried from 3.9.7 to 5.9.3

⏯ Playground Link

💻 Code

This issue with function:

function make<T, S=T, D=undefined>(value: T, options: NewOptions<T, S, D>) {
  return {
    v: value,
    data: options?.data,
    sourceValue: options?.sourceValue ?? value,
    finaleValue: options?.finaleValue,
  };
}

export type NewOptions<T, S, D> = {
  finaleValue?: T,
  sourceValue?: S,
  data: D,
};

const instance_withError = make(0, {
   // Error here: `Type '{ test(): number; }' is not assignable to type 'undefined'.(2322)`?
    data: {
        test() {
            return 123;
        },
    },
});

const data = {
    test() {
        return 123;
    },
};
// no error here
const instance1 = make(0, {
    // data is not inline object, BUT object with non-arrow function
    data,
    sourceValue: 'test',
    finaleValue: 1,
});

// no error here
const instance2 = make(0, {
    // data is inline object, BUT object with arrow function
    data: {
         test: () => {
            return 123;
        },
    },
    sourceValue: 1,
    finaleValue: 2,
});
const sV1 = instance2.sourceValue;
//    ^?
const v1 = instance2.v;
//    ^?


const sV2 = instance1.sourceValue;
//    ^?
const v2 = instance1.v;
//    ^?


// Should be `{ test(): number; }`
const data_invalid = instance_withError.data;
//    ^?
// Should be `{ test(): number; }`
const data1 = instance1.data;
//    ^?
// Should be `{ test: () => number; }`
const data2 = instance2.data;
//    ^?

🙁 Actual behavior

  1. An error occurs:
    Type '{ test(): number; }' is not assignable to type 'undefined'.(2322)
  2. data type is undefined

🙂 Expected behavior

  1. No error occurs
  2. data type is { test(): number; }

Metadata

Metadata

Assignees

No one assigned

    Labels

    FixedA PR has been merged for this issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions