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

[T] tuple type information is lost as T[] #8276

Closed
nathancahill opened this issue Apr 24, 2016 · 7 comments
Closed

[T] tuple type information is lost as T[] #8276

nathancahill opened this issue Apr 24, 2016 · 7 comments
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead

Comments

@nathancahill
Copy link

nathancahill commented Apr 24, 2016

TypeScript Version:

nightly (1.9.0-dev.20160213)

Code

interface Geo {
    latlng: [number, number]  // tuple
}

function world(geo: Geo) {}

world({ latlng: [35, -112] });  // works fine

let coordinates = { latlng: [35, -112] };
world(coordinates);  // errors

let coordinatesTyped: Geo = { latlng: [35, -112] };
world(coordinatesTyped);  // works fine

Expected behavior:

Compile without errors.

Actual behavior:

Error, [T] tuple type information is lost as T[]:

Type 'number[]' is not assignable to type '[number, number]'.

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Apr 24, 2016

The type information is not being lost.
In the line

let coordinates = { latlng: [35, -112] };

the inferred type of the object literal is

{ latlng: number[]; };

not Geo.
It is unrelated to the function call itself. When you define the object literal directly in the call as in

world({ latlng: [35, -112] });

it is target typed based on the function's parameter type to that more specific type.

While it is not entirely clear what the type of coordinates should be, note that

var t = [1, 2]; // t has type number[]
var [x, y] = [1, 2]; // x and y are of type number, there is no name for the tuple itself.

At any rate, neither the interface Geo nor the function world are taking part in type inference. They are red herrings.

@nathancahill
Copy link
Author

My point is that [35, -112] could be number[] or [number, number]. The compiler is deciding that it's number[] and throwing an error when is used as [number, number].

@aluanhaddad
Copy link
Contributor

Which is why I said it's not entirely clear what the type should be. Either one will be incompatible with certain signatures or assignments.

@aluanhaddad
Copy link
Contributor

I suppose it could be

number[] & [number, number];

But that could get out of hand pretty quickly

@ahejlsberg
Copy link
Member

This is by design. An array literal is considered a tuple only if it is contextually typed by a tuple type; for example, if it is assigned to a variable of a tuple type or passed as an argument for a parameter of a tuple type. In cases where the context provides no clear indication that it should be a tuple, we treat it as an array. It's not clear what else we would do, but we're certainly open to suggestions.

@aluanhaddad
Copy link
Contributor

I think the current behavior matches the syntactic intuition that follows from the respective declaration forms for tuples and arrays.

@nathancahill
Copy link
Author

Ok, thanks guys!

@DanielRosenwasser DanielRosenwasser added the By Design Deprecated - use "Working as Intended" or "Design Limitation" instead label Apr 25, 2016
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
By Design Deprecated - use "Working as Intended" or "Design Limitation" instead
Projects
None yet
Development

No branches or pull requests

4 participants