Skip to content

Generic return type inferred only with explicitly typed (not inferred) parameter #31892

Closed
@Diniden

Description

@Diniden

TypeScript Version: 3.6.0-dev.20190613, 3.5.1

Search Terms: Generic Inferred Return Type

Code

This is an example of the inferred return type being unknown

type TestType = {};

interface ITest<TProperty, TReturn> {
  option: TProperty;
  test(val: TProperty): TReturn;
  check(val: TReturn): void;
}

class ClassTest<TProperty, TReturn> {
  constructor(_o: ITest<TProperty, TReturn>) {
    // yay
  }
}

new ClassTest({
  option: {},

  // val parameter properly infers the type of option
  test: _val => ({
    yo: { yo: {} },
  }),

  // Val's type is 'unknown' and not the return type of test :(
  check: val => { 
    val.yo;
  }
});

With a tiny change to setting the inferred property to an explicit type, it works great now:

type TestType = {};

interface ITest<TProperty, TReturn> {
  option: TProperty;
  test(val: TProperty): TReturn;
  check(val: TReturn): void;
}

class ClassTest<TProperty, TReturn> {
  constructor(_o: ITest<TProperty, TReturn>) {
    // yay
  }
}

new ClassTest({
  option: {},

  // We explicitly set the type this time
  test: (_val: TestType) => ({
    yo: { yo: {} },
  }),

  // Val's type is magically known :)
  check: val => { 
    val.yo;
  }
});

Expected behavior:

The TReturn should be inferred whether the TProperty is explicitly set in the parameter of the test method or not.

I would expect this because the system is able to infer TProperty just fine without me setting it in test.

Actual behavior:

TReturn is only inferred if TProperty for the parameter in the method is explicitly set even though TProperty can be inferred from the property just fine.

Playground Link:

Failing inference:
fails

Fixed inference:
works

Metadata

Metadata

Assignees

No one assigned

    Labels

    Design LimitationConstraints of the existing architecture prevent this from being fixed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions