-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
3.4.1 breaks backward compatibility for users of ReadonlyArray #30662
Comments
I already reported that in #29435 (comment). This was also discussed in the release planning of v3.4 #30281:
But it seems there were no further actions to mitigate those breaks.
You could use the workspace version of TypeScript instead of the version that comes bundled with VSCode.
That is actually the case if you declare something like I created a transformer to downlevel readonly array types in declaration files for backwards compatibility: https://github.com/ajafff/ts-transform-readonly-array |
Thanks for this additional information. I was not able to find it between all the irrelevant search results showing up on various keywords.
I think the TypeScript team is underestimating just how big of a breaking change this is. This will completely split the ecosystem into pre-3.4 and post-3.4 type definitions. Since 3.4 (and a couple versions before that) also introduce breaking changes in projects themselves, and most of those project's maintainers likely don't have the time or resources to fix those issues, a significant portion of the ecosystem will not be able to make this update anytime soon. This forces all libraries who happen to know about this, and care about their users, to stay on 3.3, or if they don't know about this, they will break everything downstream until someone reports an issue.
It doesn't work. As you can see in my repro example, I am using the vscode settings to explicitly point to the workspace version.
I don't understand the benefit of this. I understood this feature as being syntactic sugar - having a nice concise way to declare a Why the decision to make this breaking change about as breaking as it could possibly be, out of all the possible flavors that could have been picked? And why do this in a minor version bump?
This is great, thanks for that. This really ought to be a built-in opt-out with this patch, with an explicit flag to actually emit I really like the later features of TypeScript. The team is doing a great job here. But this kind of versioning, in my opinion, is subpar. Surely, one should be able to upgrade a minor version without having to worry about breaking changes at all, certainly of this magniture? @DanielRosenwasser would you guys please consider emitting |
This is a bit off topic, but: TypeScript doesn't follow (or claim to follow) semantic versioning, so it's more of a "why not". |
Right, I found this hidden away issue about semver and it seems that the major version is marketing, the minor version is breaking, and the patch is anything feature or bugfix related. Good to know. This is still a pretty nasty one considering it affects all inferred types as you say, which includes the commonly used |
@DanielRosenwasser When you are back in office, it would be great to get some eyes on this. I think this change has likely created a bigger issue than anticipated, or the effects were accidentally overlooked. I'd love to hear what can be done to make this better. |
For anyone reading and thinking that they're blocked by this, In any case where your declaration file output would be impacted by this, you can explicitly write the annotation including export const x = Object.freeze([1,2,3]);
// Emits `export const x: readonly number[]
export const y: ReadonlyArray<number> = Object.freeze([1,2,3]);
// Emits `export const x: ReadonlyArray<number> as written We've gone thru the same process with a number of new type-syntax features that get used in declaration files, including import types, tuple types, conditional types... Pretty much every time we add a new form of type (this time we added readonly tuples by extended the syntax to cover arrays). So, taking your example in the OP: export const PLATFORM: { global: {}, emptyArray: ReadonlyArray<never>, emptyObject: Readonly<{}>, noop: () => {} } = {
global: {},
emptyArray: Object.freeze([]),
emptyObject: Object.freeze({}),
noop: () => {},
}; Canonically, this is how you deal with new syntax finding its way into declaration files - you simply explicitly override it with the (backwards compatible) syntax you want. |
@weswigham Thank you for the clarification. I'll close this since there isn't really any action to be taken here. |
When I tried to update aurelia to the latest TypeScript version, intellisense broke left right and center while the build still succeeds. It appears that
ReadonlyArray<never>
is emitted asreadonly never[]
in the type definitions, and the current version of VS Code doesn't understand that.TypeScript Version: 3.4.1
Search Terms: 3.4.1, ReadonlyArray, readonly
Code
This is the source code:
Where the
emptyArray
resolves toReadonlyArray<never>
:This is the generated type definition:
And this is what code consuming that type definition will see:
Repro:
Not sure how to reproduce this on the typescript playground because it relies on cross-package references, so here is a minimal repro here:
All will succeed. Now, open
packages/runtime/src/index.ts
and you'll see the problem:The
ReadonlyArray<any>
falls back toany
, and any properties after seem to disappear.Expected behavior:
I would expect
ReadonlyArray<never>
to be emitted asReadonlyArray<never>
in the type definitions.Actual behavior:
It is emitted as
readonly never[]
.This breaks backwards compatibility for anyone using
ReadonlyArray
and building with 3.4.1+, and will force all consumers to use this same version of TypeScript. Which includes VS Code at the moment :)The text was updated successfully, but these errors were encountered: