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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions