-
Notifications
You must be signed in to change notification settings - Fork 12.8k
Type parameter on ts.some/ts.find is too narrow when called on union of arrays, works with explicit instantiation #52179
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
Comments
I will say that the first overload to export function some(array: readonly unknown[] | undefined): array is readonly unknown[]; And function the same way (proving the array isn't undefined), but the callback case is the one that errors in the SFT branch. |
This is another case on the SFT branch: Playground Link enum SyntaxKind {
Block,
Identifier,
CaseClause,
FunctionExpression,
FunctionDeclaration,
}
interface Node { kind: SyntaxKind; }
interface Expression extends Node { _expressionBrand: any; }
interface Declaration extends Node { _declarationBrand: any; }
interface Block extends Node { kind: SyntaxKind.Block; }
declare function find<T, U extends T>(array: readonly T[] | undefined, predicate: (element: T, index: number) => element is U, startIndex?: number): U | undefined;
declare function find<T>(array: readonly T[] | undefined, predicate: (element: T, index: number) => boolean, startIndex?: number): T | undefined;
function foo(array: readonly Declaration[] | readonly Block[] | undefined) {
const a = find(array, (node) => true); // error!
// ^?
const b = find<Declaration | Block>(array, (node) => true);
// ^?
const c = find<Node>(array, (node) => true);
// ^?
} |
So, this extends past |
@ahejlsberg for interest. |
Then there's this... // @strict: true
const enum SyntaxKind {
Modifier,
Decorator,
}
interface Node {
kind: SyntaxKind;
}
interface Modifier extends Node { kind: SyntaxKind.Modifier; }
interface Decorator extends Node { kind: SyntaxKind.Decorator; }
declare function isModifier(node: Node): node is Modifier;
declare function isDecorator(node: Node): node is Decorator;
declare function every<T, U extends T>(array: readonly T[], callback: (element: T) => element is U): array is readonly U[];
declare const modifiers: readonly Modifier[] | readonly Decorator[];
function foo() {
every(modifiers, isModifier); // error? (undesired)
every(modifiers, isDecorator); // no error (desired)
} Swap the union order on |
Unbelievably, I figured out what might be a fix for |
Regarding the error with function foo(array: readonly Declaration[] | readonly Block[] | undefined) {
const a = find(array, (node) => true); // error!
// ^?
const b = find<Declaration | Block>(array, (node) => true);
// ^?
const c = find<Node>(array, (node) => true);
// ^?
} It's not clear there's anything we can do here. Neither of the co-variant inferences we make for |
Yeah, I had found some more examples that already existed in the codebase pre-SFT like this. I'm going to retest SFT with #52180 as LKG and see how far we get; I'm guessing it will turn out okay. |
This is a follow-up to #52111 and #52123.
In the below code,
every
works as expected, which is new as of #52123. However, thesome
function can't be called on the array type at all, even though reasonably there's a top type which works (A
), just like it works forevery
.Output
Compiler Options
Playground Link: Provided
The text was updated successfully, but these errors were encountered: