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

Regression in array destruction in TypeScript 3.3 #29731

Closed
sergey-shandar opened this issue Feb 4, 2019 · 5 comments
Closed

Regression in array destruction in TypeScript 3.3 #29731

sergey-shandar opened this issue Feb 4, 2019 · 5 comments
Assignees
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@sergey-shandar
Copy link
Contributor

sergey-shandar commented Feb 4, 2019

TypeScript Version: 3.3.1 and 3.4.1

Search Terms:

Code

type ImmutableTuple2 = {
    readonly [0]: number
    readonly [1]: string
} & Iterable<number|string>

const f = <T>(_v: T, _c: (v: T) => void) => {}

const v: ImmutableTuple2 = [4, "hello"]

f(v, ([a, b]) => {
    const _a: number = a // a should be a `number` but it's `number`|`string` in TS 3.3
    const _b: string = b // b should be a `string` but it's `number`|`string` in TS 3.3
})

Expected behavior:
No compilation errors. (TypeScript 3.2)

Actual behavior:

TypeScript 3.3.1 and up

src/test.ts:11:11 - error TS2322: Type 'string | number' is not assignable to type 'number'.
  Type 'string' is not assignable to type 'number'.

11     const _a: number = a
             ~~

src/test.ts:12:11 - error TS2322: Type 'string | number' is not assignable to type 'string'.
  Type 'number' is not assignable to type 'string'.

12     const _b: string = b
             ~~


Found 2 errors

Playground Link:

Related Issues:

@sergey-shandar
Copy link
Contributor Author

sergey-shandar commented Feb 4, 2019

Simplified code

type ImmutableTuple2 = {
    readonly [0]: number
    readonly [1]: string
} & Iterable<number|string>

const f = ([a, b]: ImmutableTuple2) => {
    const _a: number = a // a should be a `number` but it's `number`|`string` in TS 3.3
    const _b: string = b // b should be a `string` but it's `number`|`string` in TS 3.3
}

@sergey-shandar
Copy link
Contributor Author

Workaround # 1

const f = (ab: ImmutableTuple2) => {
    const _a: number = ab[0] // ok
    const _b: string = ab[1] // ok
}

Workaround # 2

const f = (ab: ImmutableTuple2) => {
    const [a, b] = ab
    const _a: number = a // ok
    const _b: string = b // ok
}

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Feb 5, 2019
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.4.0 milestone Feb 5, 2019
@sergey-shandar
Copy link
Contributor Author

The bug is also in TypeScript 3.4.1.

@vladbarosan
Copy link

@ahejlsberg is there any expected release when this to be fixed ?

@ahejlsberg ahejlsberg added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Needs Investigation This issue needs a team member to investigate its status. labels Jun 7, 2019
@ahejlsberg
Copy link
Member

Starting with TypeScript 3.4 we have proper support for readonly arrays and tuples (see #29435). The original example can now be written:

const f = <T>(_v: T, _c: (v: T) => void) => {}

const v: readonly [number, string] = [4, "hello"]

f(v, ([a, b]) => {
    const _a: number = a;
    const _b: string = b;
})

We no longer recognize "pseudo-tuples" like ImmutableTuple2 and given the intrinsic support I don't think adding more complexity in this area is worth it. So, I'm closing this issue.

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