Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type argument inference does not take call's contextual type into account #10245

Closed
zakjan opened this issue Aug 10, 2016 · 4 comments
Closed
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript

Comments

@zakjan
Copy link

zakjan commented Aug 10, 2016

TypeScript Version: 2.0.0

Code

function map(array: number[]): [number, number][] {
    return array.map((x: number) => [x, x * x]);
}

Expected behavior:
no error

Actual behavior:

error TS2322: Type 'number[][]' is not assignable to type '[number, number][]'.
  Type 'number[]' is not assignable to type '[number, number]'.
    Property '0' is missing in type 'number[]'.
@DanielRosenwasser
Copy link
Member

DanielRosenwasser commented Aug 10, 2016

What's happening here is that the call to array.map doesn't try to infer its return type from its contextual type. It only tries to infer from its arguments.

A workaround would be to give [number, number] as a type argument to map:

function map(array: number[]) {
    return array.map<[number, number]>(x => [x, x * x]);
}

@DanielRosenwasser DanielRosenwasser added Suggestion An idea for TypeScript Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. labels Aug 10, 2016
@DanielRosenwasser DanielRosenwasser changed the title Incorrect contextual type inferred Type argument inference does not take call's contextual type into account Aug 10, 2016
@manueledones
Copy link

manueledones commented Jan 16, 2019

@DanielRosenwasser Here some other examples:

export interface DataModel {
  prop1: string;
  prop2: number;
}

const array = [1,2,3,4];

// NO ERROR
const datamodels2: DataModel[] = array.map(i => ({
  prop1: 'asdf',
  prop2: 1234,
  extra: 'extra'
}))

// NO ERROR
const datamodels4: DataModel[] = array.map(i => {
  return {
    prop1: 'asdf',
    prop2: 1234,
    extra: 'extra'
  } 
});

// NO ERROR
const datamodels5: DataModel[] = array.map(i => {
    return {
        prop1: 'asdf',
        prop2: 1234,
        extra: 'extra'
    }  as DataModel
});

// NO ERROR
const datamodels6: DataModel[] = array.map(i => ({
        prop1: 'asdf',
        prop2: 1234,
        extra: 'extra'
}) as DataModel);

// NO ERROR
const datamodels7: DataModel[] = array.map<DataModel>(i => ({
        prop1: 'asdf',
        prop2: 1234,
        extra: 'extra'
}));

`
Is this the expected behavior or a bug?

@RyanCavanaugh
Copy link
Member

@whiteblackkeys Unrelated. Root cause is #241 - function return expression widening causes the object literal freshness to be lost, causing excess properties to not be checked.

@ahejlsberg
Copy link
Member

Fixed by #29478.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants