Defer checking expressions in void expressions (#56122)

This commit is contained in:
Mateusz Burzyński 2023-10-16 19:16:19 +02:00 committed by GitHub
parent 2e660bc174
commit 0e07ff50ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 125 additions and 1 deletions

View File

@ -37085,7 +37085,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function checkVoidExpression(node: VoidExpression): Type {
checkExpression(node.expression);
checkNodeDeferred(node);
return undefinedWideningType;
}
@ -46198,6 +46198,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
case SyntaxKind.ParenthesizedExpression:
checkAssertionDeferred(node as AssertionExpression | JSDocTypeAssertion);
break;
case SyntaxKind.VoidExpression:
checkExpression((node as VoidExpression).expression);
break;
case SyntaxKind.BinaryExpression:
if (isInstanceOfExpression(node)) {
resolveUntypedCall(node);

View File

@ -0,0 +1,49 @@
//// [tests/cases/compiler/avoidCycleWithVoidExpressionReturnedFromArrow.ts] ////
=== avoidCycleWithVoidExpressionReturnedFromArrow.ts ===
type HowlErrorCallback = (soundId: number, error: unknown) => void;
>HowlErrorCallback : Symbol(HowlErrorCallback, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 0, 0))
>soundId : Symbol(soundId, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 0, 26))
>error : Symbol(error, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 0, 42))
interface HowlOptions {
>HowlOptions : Symbol(HowlOptions, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 0, 67))
onplayerror?: HowlErrorCallback | undefined;
>onplayerror : Symbol(HowlOptions.onplayerror, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 2, 23))
>HowlErrorCallback : Symbol(HowlErrorCallback, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 0, 0))
}
class Howl {
>Howl : Symbol(Howl, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 4, 1))
constructor(public readonly options: HowlOptions) {}
>options : Symbol(Howl.options, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 7, 14))
>HowlOptions : Symbol(HowlOptions, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 0, 67))
once(name: "unlock", fn: () => void) {
>once : Symbol(Howl.once, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 7, 54))
>name : Symbol(name, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 8, 7))
>fn : Symbol(fn, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 8, 22))
console.log(name, fn);
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>name : Symbol(name, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 8, 7))
>fn : Symbol(fn, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 8, 22))
}
}
const instance = new Howl({
>instance : Symbol(instance, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 13, 5))
>Howl : Symbol(Howl, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 4, 1))
onplayerror: () => void instance.once("unlock", () => {}),
>onplayerror : Symbol(onplayerror, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 13, 27))
>instance.once : Symbol(Howl.once, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 7, 54))
>instance : Symbol(instance, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 13, 5))
>once : Symbol(Howl.once, Decl(avoidCycleWithVoidExpressionReturnedFromArrow.ts, 7, 54))
});

View File

@ -0,0 +1,53 @@
//// [tests/cases/compiler/avoidCycleWithVoidExpressionReturnedFromArrow.ts] ////
=== avoidCycleWithVoidExpressionReturnedFromArrow.ts ===
type HowlErrorCallback = (soundId: number, error: unknown) => void;
>HowlErrorCallback : (soundId: number, error: unknown) => void
>soundId : number
>error : unknown
interface HowlOptions {
onplayerror?: HowlErrorCallback | undefined;
>onplayerror : HowlErrorCallback | undefined
}
class Howl {
>Howl : Howl
constructor(public readonly options: HowlOptions) {}
>options : HowlOptions
once(name: "unlock", fn: () => void) {
>once : (name: "unlock", fn: () => void) => void
>name : "unlock"
>fn : () => void
console.log(name, fn);
>console.log(name, fn) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
>name : "unlock"
>fn : () => void
}
}
const instance = new Howl({
>instance : Howl
>new Howl({ onplayerror: () => void instance.once("unlock", () => {}),}) : Howl
>Howl : typeof Howl
>{ onplayerror: () => void instance.once("unlock", () => {}),} : { onplayerror: () => undefined; }
onplayerror: () => void instance.once("unlock", () => {}),
>onplayerror : () => undefined
>() => void instance.once("unlock", () => {}) : () => undefined
>void instance.once("unlock", () => {}) : undefined
>instance.once("unlock", () => {}) : void
>instance.once : (name: "unlock", fn: () => void) => void
>instance : Howl
>once : (name: "unlock", fn: () => void) => void
>"unlock" : "unlock"
>() => {} : () => void
});

View File

@ -0,0 +1,19 @@
// @strict: true
// @noEmit: true
type HowlErrorCallback = (soundId: number, error: unknown) => void;
interface HowlOptions {
onplayerror?: HowlErrorCallback | undefined;
}
class Howl {
constructor(public readonly options: HowlOptions) {}
once(name: "unlock", fn: () => void) {
console.log(name, fn);
}
}
const instance = new Howl({
onplayerror: () => void instance.once("unlock", () => {}),
});