mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-10 18:04:18 -05:00
Fixed an issue with errors not being correctly reported after completion requests in functions within nested calls (#54944)
This commit is contained in:
committed by
GitHub
parent
05fdb5f671
commit
21b8892d21
@@ -1836,20 +1836,30 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
};
|
||||
|
||||
function runWithoutResolvedSignatureCaching<T>(node: Node | undefined, fn: () => T): T {
|
||||
const cachedSignatures = [];
|
||||
const cachedResolvedSignatures = [];
|
||||
const cachedTypes = [];
|
||||
while (node) {
|
||||
if (isCallLikeExpression(node)) {
|
||||
if (isCallLikeExpression(node) || isFunctionLike(node)) {
|
||||
const nodeLinks = getNodeLinks(node);
|
||||
const resolvedSignature = nodeLinks.resolvedSignature;
|
||||
cachedSignatures.push([nodeLinks, resolvedSignature] as const);
|
||||
cachedResolvedSignatures.push([nodeLinks, resolvedSignature] as const);
|
||||
nodeLinks.resolvedSignature = undefined;
|
||||
}
|
||||
if (isFunctionLike(node)) {
|
||||
const symbolLinks = getSymbolLinks(getSymbolOfDeclaration(node));
|
||||
const type = symbolLinks.type;
|
||||
cachedTypes.push([symbolLinks, type] as const);
|
||||
symbolLinks.type = undefined;
|
||||
}
|
||||
node = node.parent;
|
||||
}
|
||||
const result = fn();
|
||||
for (const [nodeLinks, resolvedSignature] of cachedSignatures) {
|
||||
for (const [nodeLinks, resolvedSignature] of cachedResolvedSignatures) {
|
||||
nodeLinks.resolvedSignature = resolvedSignature;
|
||||
}
|
||||
for (const [symbolLinks, type] of cachedTypes) {
|
||||
symbolLinks.type = type;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
Syntactic Diagnostics for file '/tests/cases/fourslash/typeErrorAfterStringCompletionsInNestedCall2.ts':
|
||||
|
||||
|
||||
==== /tests/cases/fourslash/typeErrorAfterStringCompletionsInNestedCall2.ts (0 errors) ====
|
||||
|
||||
type ActionFunction<
|
||||
TExpressionEvent extends { type: string },
|
||||
out TEvent extends { type: string }
|
||||
> = {
|
||||
({ event }: { event: TExpressionEvent }): void;
|
||||
_out_TEvent?: TEvent;
|
||||
};
|
||||
|
||||
interface MachineConfig<TEvent extends { type: string }> {
|
||||
types: {
|
||||
events: TEvent;
|
||||
};
|
||||
on: {
|
||||
[K in TEvent["type"]]?: ActionFunction<
|
||||
Extract<TEvent, { type: K }>,
|
||||
TEvent
|
||||
>;
|
||||
};
|
||||
}
|
||||
|
||||
declare function raise<
|
||||
TExpressionEvent extends { type: string },
|
||||
TEvent extends { type: string }
|
||||
>(
|
||||
resolve: ({ event }: { event: TExpressionEvent }) => TEvent
|
||||
): {
|
||||
({ event }: { event: TExpressionEvent }): void;
|
||||
_out_TEvent?: TEvent;
|
||||
};
|
||||
|
||||
declare function createMachine<TEvent extends { type: string }>(
|
||||
config: MachineConfig<TEvent>
|
||||
): void;
|
||||
|
||||
createMachine({
|
||||
types: {
|
||||
events: {} as { type: "FOO" } | { type: "BAR" },
|
||||
},
|
||||
on: {
|
||||
FOO: raise(({ event }) => {
|
||||
return {
|
||||
type: "BAR" as const,
|
||||
};
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
Semantic Diagnostics for file '/tests/cases/fourslash/typeErrorAfterStringCompletionsInNestedCall2.ts':
|
||||
/tests/cases/fourslash/typeErrorAfterStringCompletionsInNestedCall2.ts(41,5): error TS2322: Type '{ ({ event }: { event: { type: "FOO"; }; }): void; _out_TEvent?: { type: "BARx"; } | undefined; }' is not assignable to type 'ActionFunction<{ type: "FOO"; }, { type: "FOO"; } | { type: "BAR"; }>'.
|
||||
Types of property '_out_TEvent' are incompatible.
|
||||
Type '{ type: "BARx"; } | undefined' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; } | undefined'.
|
||||
Type '{ type: "BARx"; }' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; } | undefined'.
|
||||
Type '{ type: "BARx"; }' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; }'.
|
||||
Type '{ type: "BARx"; }' is not assignable to type '{ type: "BAR"; }'.
|
||||
Types of property 'type' are incompatible.
|
||||
Type '"BARx"' is not assignable to type '"BAR"'.
|
||||
|
||||
|
||||
==== /tests/cases/fourslash/typeErrorAfterStringCompletionsInNestedCall2.ts (1 errors) ====
|
||||
|
||||
type ActionFunction<
|
||||
TExpressionEvent extends { type: string },
|
||||
out TEvent extends { type: string }
|
||||
> = {
|
||||
({ event }: { event: TExpressionEvent }): void;
|
||||
_out_TEvent?: TEvent;
|
||||
};
|
||||
|
||||
interface MachineConfig<TEvent extends { type: string }> {
|
||||
types: {
|
||||
events: TEvent;
|
||||
};
|
||||
on: {
|
||||
[K in TEvent["type"]]?: ActionFunction<
|
||||
Extract<TEvent, { type: K }>,
|
||||
TEvent
|
||||
>;
|
||||
};
|
||||
}
|
||||
|
||||
declare function raise<
|
||||
TExpressionEvent extends { type: string },
|
||||
TEvent extends { type: string }
|
||||
>(
|
||||
resolve: ({ event }: { event: TExpressionEvent }) => TEvent
|
||||
): {
|
||||
({ event }: { event: TExpressionEvent }): void;
|
||||
_out_TEvent?: TEvent;
|
||||
};
|
||||
|
||||
declare function createMachine<TEvent extends { type: string }>(
|
||||
config: MachineConfig<TEvent>
|
||||
): void;
|
||||
|
||||
createMachine({
|
||||
types: {
|
||||
events: {} as { type: "FOO" } | { type: "BAR" },
|
||||
},
|
||||
on: {
|
||||
FOO: raise(({ event }) => {
|
||||
~~~
|
||||
!!! error TS2322: Type '{ ({ event }: { event: { type: "FOO"; }; }): void; _out_TEvent?: { type: "BARx"; } | undefined; }' is not assignable to type 'ActionFunction<{ type: "FOO"; }, { type: "FOO"; } | { type: "BAR"; }>'.
|
||||
!!! error TS2322: Types of property '_out_TEvent' are incompatible.
|
||||
!!! error TS2322: Type '{ type: "BARx"; } | undefined' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; } | undefined'.
|
||||
!!! error TS2322: Type '{ type: "BARx"; }' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; } | undefined'.
|
||||
!!! error TS2322: Type '{ type: "BARx"; }' is not assignable to type '{ type: "FOO"; } | { type: "BAR"; }'.
|
||||
!!! error TS2322: Type '{ type: "BARx"; }' is not assignable to type '{ type: "BAR"; }'.
|
||||
!!! error TS2322: Types of property 'type' are incompatible.
|
||||
!!! error TS2322: Type '"BARx"' is not assignable to type '"BAR"'.
|
||||
!!! related TS6500 /tests/cases/fourslash/typeErrorAfterStringCompletionsInNestedCall2.ts:14:7: The expected type comes from property 'FOO' which is declared here on type '{ FOO?: ActionFunction<{ type: "FOO"; }, { type: "FOO"; } | { type: "BAR"; }> | undefined; BAR?: ActionFunction<{ type: "BAR"; }, { type: "FOO"; } | { type: "BAR"; }> | undefined; }'
|
||||
return {
|
||||
type: "BAR" as const,
|
||||
};
|
||||
}),
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,54 @@
|
||||
///<reference path="fourslash.ts"/>
|
||||
// @strict: true
|
||||
////
|
||||
//// type ActionFunction<
|
||||
//// TExpressionEvent extends { type: string },
|
||||
//// out TEvent extends { type: string }
|
||||
//// > = {
|
||||
//// ({ event }: { event: TExpressionEvent }): void;
|
||||
//// _out_TEvent?: TEvent;
|
||||
//// };
|
||||
////
|
||||
//// interface MachineConfig<TEvent extends { type: string }> {
|
||||
//// types: {
|
||||
//// events: TEvent;
|
||||
//// };
|
||||
//// on: {
|
||||
//// [K in TEvent["type"]]?: ActionFunction<
|
||||
//// Extract<TEvent, { type: K }>,
|
||||
//// TEvent
|
||||
//// >;
|
||||
//// };
|
||||
//// }
|
||||
////
|
||||
//// declare function raise<
|
||||
//// TExpressionEvent extends { type: string },
|
||||
//// TEvent extends { type: string }
|
||||
//// >(
|
||||
//// resolve: ({ event }: { event: TExpressionEvent }) => TEvent
|
||||
//// ): {
|
||||
//// ({ event }: { event: TExpressionEvent }): void;
|
||||
//// _out_TEvent?: TEvent;
|
||||
//// };
|
||||
////
|
||||
//// declare function createMachine<TEvent extends { type: string }>(
|
||||
//// config: MachineConfig<TEvent>
|
||||
//// ): void;
|
||||
////
|
||||
//// createMachine({
|
||||
//// types: {
|
||||
//// events: {} as { type: "FOO" } | { type: "BAR" },
|
||||
//// },
|
||||
//// on: {
|
||||
//// [|/*error*/FOO|]: raise(({ event }) => {
|
||||
//// return {
|
||||
//// type: "BAR/*1*/" as const,
|
||||
//// };
|
||||
//// }),
|
||||
//// },
|
||||
//// });
|
||||
|
||||
goTo.marker("1");
|
||||
edit.insert(`x`)
|
||||
verify.completions({ exact: ["FOO", "BAR"] });
|
||||
verify.baselineSyntacticAndSemanticDiagnostics()
|
||||
Reference in New Issue
Block a user