-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Remove assignability cases in getNarrowedType + an isArray improvement for readonly arrays #39258
Conversation
@typescript-bot test this |
Heya @RyanCavanaugh, I've started to run the parallelized community code test suite on this PR at 855fd84. You can monitor the build here. |
Heya @RyanCavanaugh, I've started to run the extended test suite on this PR at 855fd84. You can monitor the build here. |
The user suite test run you requested has finished and failed. I've opened a PR with the baseline diff from master. |
@typescript-bot test this |
Heya @RyanCavanaugh, I've started to run the parallelized community code test suite on this PR at ed01085. You can monitor the build here. |
Heya @RyanCavanaugh, I've started to run the extended test suite on this PR at ed01085. You can monitor the build here. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is going to work. See https://mseng.visualstudio.com/Typescript/_git/Typescript/pullrequest/560730?_a=files for RWC breaks
Seems to be tripping up when the guarded value has type declare function isArray<T>(arg: T | {}): arg is T extends readonly (infer U)[] ? GroundArray<T,U>: any[];
type GroundArray<T extends readonly unknown[], U> = [T] extends [U[]] ? any[] : T; |
isArray<T>(arg: T | {}): arg is T extends readonly any[] ? (unknown extends T ? never : readonly any[]) : any[]; should also work to filter out |
@typescript-bot test this |
OK, so that does clean up most of the errors in the RWC in the azure side - it looks like just a few rxjs issues and they all stem to their own custom export const isArray = (() => Array.isArray || (<T>(x: any): x is T[] => x && typeof x.length === 'number'))(); We're still seeing issues in this PR: typescript-bot#53
this could be because they have their own export function isArray(array: any): array is any[] {
return Array.isArray(array);
} I could update the vscode definition to the new definition to see if that fixes it |
Yeah, the custom |
Looks like I need a build to verify rxjs @typescript-bot pack this |
Hey @orta, I've packed this into an installable tgz. You can install it for testing by referencing it in your
and then running There is also a playground for this build. |
@typescript-bot pack this |
I'll merge on tuesday when I'm off DT rotation 👍🏻 |
Today is that tuesday, I'm going to merge 👍🏻 |
Typescript 4.1 will have [stricter rules for type predicates](microsoft/TypeScript#39258) like ```ts export const isObject = (val: unknown): val is Record<any, any> => val !== null && typeof val === 'object' ``` As a result of these rules, an expression in collectionHandlers.ts in the reactivity package doesn't get narrowed to the type it did in TS 4.0 and below. Instead it gets an intersection type, which doesn't work with subsequent code. I restored the old type using a cast, since that's essentially what the old version of Typescript was doing here.
Example for blog post declare const p: string | ReadonlyArray<string>;
if (Array.isArray(p)) {
// 4.0: p: any[]
// 4.1: p: readonly string[];
// 4.0: OK
// 4.1: Error
p.push(0);
} |
FWIW, possibly a better example for the blogpost is one where TypeScript narrowed the type incorrectly and unsafely, rather than merely providing a weaker-than-desired type, e.g.: declare var foo: string[] | readonly number[] | null
if (foo instanceof Array) {
foo; // at runtime, this may be string[] or readonly number[],
// however, TypeScript <4.1 would narrow to just string[]
foo.push('str'); // incorrect and unsafe, but allowed by <4.1, now errors in Nightly
} else {
foo; // at runtime, strictly null, however TypeScript <4.1 would
// narrow to readonly number[] | null
} |
@orta / @RyanCavanaugh This PR has the https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#typescript-41 |
This is broken for generics and other nontrivial types: declare function f1<T extends any[]>(array: T): void;
function f2<T>(thing: T) {
if (Array.isArray(thing)) {
f1(thing); // Argument of type 'T & (T extends readonly any[] ? unknown extends T ? never : readonly any[] : any[])' is not assignable to parameter of type 'any[]'.
}
} In 4.0, the type of |
Another issue caused by the improvement: #41714 |
Fixes #31155
Fixes #17002
There are two pieces to this PR:
The 2nd was blocked on :
Where :
Is now legal due to changes in the
isArray
definition which takes into accountreadonly
arrays./cc @jack-williams