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

Assign tuple to object: Number is not assignable to type literal #24680

Closed
mstn opened this issue Jun 5, 2018 · 4 comments
Closed

Assign tuple to object: Number is not assignable to type literal #24680

mstn opened this issue Jun 5, 2018 · 4 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@mstn
Copy link

mstn commented Jun 5, 2018

TypeScript Version: 3.0.0-dev.20180602

Search Terms:

number is not assignable with type literal, tuple assigned to object, fixed size tuples

Code

// Type Error: number is not assignable with type 2
let p0: { length: 2 } = [1, 2]; 
// ok
let p1: { length: 2, 0: number } = [1, 2]
// ok
let p2: { 0: number } = [1, 2]

Expected behavior:

After that, [number, number] type should be equivalent to:

interface Tuple extends Array<number> {
    0: number;
    1: number;
    length: 2;
}
let t: Tuple = [1, 2];
// no syntax error
let obj: { length: 2 } = t;

Hence, I would expect let p0: { length: 2 } = [1, 2]; to be correct.

Please not that let p1: { length: 2, 0: number } = [1, 2]; is allowed.

Actual behavior:

let p0: { length: 2 } = [1, 2]; is not correct and gives error Number is not assignable to type 2.

Playground Link:

Playground snippet

@DanielRosenwasser DanielRosenwasser added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Jun 5, 2018
@DanielRosenwasser
Copy link
Member

Right now an array is only considered a tuple if it's contextually typed by a tuple-like type, which is really any type with a 0 property. We could consider including length in there. Is there a use-case you had in mind?

@mstn
Copy link
Author

mstn commented Jun 5, 2018

@DanielRosenwasser thanks for your answer.

If I understand correctly, you are saying that I can assign tuples only to tuple-like objects (= must have 0 property). I was thinking that, in Javascript, an array is an object and, in Typescript, it could make sense to see a tuple as a generic object, too.

I do not have a real use-case. I stumbled upon this feature while I was playing around with fixed size tuples in an attempt to define generic arrays of fixed size, such as,

// array of length 2 with items of type string
let d: FixedSizeArray<2, string>;

@AnyhowStep
Copy link
Contributor

AnyhowStep commented Jun 5, 2018

What I do for tuples,

https://github.com/AnyhowStep/typed-orm/blob/master/src/main/declaration-v2/tuple.ts

If you need a tuple of length 2, you need to check that it had the indices "0" and "1"

If you need a tuple of length 3, "0", "1", "2"

Just "0" and "length" are not really "enough" to guarantee those indices exist, after all.

I personally have no use for fixed length tuples. So, my type declarations make no reference to forcing it.

But I imagine, without "native" support for tuples of fixed length, you can implement it with copy pasting code (or writing a for-loop) and conditional types.

But using { length : number } isn't enough to guarantee the indices

@RyanCavanaugh RyanCavanaugh added Working as Intended The behavior described is the intended behavior; this is not a bug and removed In Discussion Not yet reached consensus Suggestion An idea for TypeScript labels Jun 24, 2021
@RyanCavanaugh
Copy link
Member

I think tuple-typing anything contextually typed by a length property is going to have too many false positives, and it's actually a bit of a perf hit to do anything more complex here. If people aren't hitting this in practice then I'm comfortable calling this the intended behavior ; as const is a common requirement in these scenarios.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants