Instantiate rest type as needed in getNarrowedTypeOfSymbol (#52215)

This commit is contained in:
Anders Hejlsberg
2023-01-13 07:23:39 -08:00
committed by GitHub
parent 36e9570933
commit d6de73b20a
6 changed files with 200 additions and 1 deletions
+1 -1
View File
@@ -27285,7 +27285,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
if (func.parameters.length >= 2 && isContextSensitiveFunctionOrObjectLiteralMethod(func)) {
const contextualSignature = getContextualSignature(func);
if (contextualSignature && contextualSignature.parameters.length === 1 && signatureHasRestParameter(contextualSignature)) {
const restType = getReducedApparentType(getTypeOfSymbol(contextualSignature.parameters[0]));
const restType = getReducedApparentType(instantiateType(getTypeOfSymbol(contextualSignature.parameters[0]), getInferenceContext(func)?.nonFixingMapper));
if (restType.flags & TypeFlags.Union && everyType(restType, isTupleType) && !isSymbolAssigned(symbol)) {
const narrowedType = getFlowTypeOfReference(func, restType, restType, /*flowContainer*/ undefined, location.flowNode);
const index = func.parameters.indexOf(declaration) - (getThisParameter(func) ? 1 : 0);
@@ -394,4 +394,19 @@ tests/cases/conformance/controlFlow/dependentDestructuredVariables.ts(334,5): er
}
}
}
// Repro from #52152
interface ClientEvents {
warn: [message: string];
shardDisconnect: [closeEvent: CloseEvent, shardId: number];
}
declare class Client {
public on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void): void;
}
const bot = new Client();
bot.on("shardDisconnect", (event, shard) => console.log(`Shard ${shard} disconnected (${event.code},${event.wasClean}): ${event.reason}`));
bot.on("shardDisconnect", event => console.log(`${event.code} ${event.wasClean} ${event.reason}`));
@@ -386,6 +386,21 @@ const fa3: (...args: [true, number] | [false, string]) => void = (guard, value)
}
}
}
// Repro from #52152
interface ClientEvents {
warn: [message: string];
shardDisconnect: [closeEvent: CloseEvent, shardId: number];
}
declare class Client {
public on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void): void;
}
const bot = new Client();
bot.on("shardDisconnect", (event, shard) => console.log(`Shard ${shard} disconnected (${event.code},${event.wasClean}): ${event.reason}`));
bot.on("shardDisconnect", event => console.log(`${event.code} ${event.wasClean} ${event.reason}`));
//// [dependentDestructuredVariables.js]
@@ -687,6 +702,9 @@ const fa3 = (guard, value) => {
}
}
};
const bot = new Client();
bot.on("shardDisconnect", (event, shard) => console.log(`Shard ${shard} disconnected (${event.code},${event.wasClean}): ${event.reason}`));
bot.on("shardDisconnect", event => console.log(`${event.code} ${event.wasClean} ${event.reason}`));
//// [dependentDestructuredVariables.d.ts]
@@ -827,3 +845,11 @@ declare function fa2(x: {
value: string;
}): void;
declare const fa3: (...args: [true, number] | [false, string]) => void;
interface ClientEvents {
warn: [message: string];
shardDisconnect: [closeEvent: CloseEvent, shardId: number];
}
declare class Client {
on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void): void;
}
declare const bot: Client;
@@ -965,3 +965,73 @@ const fa3: (...args: [true, number] | [false, string]) => void = (guard, value)
}
}
// Repro from #52152
interface ClientEvents {
>ClientEvents : Symbol(ClientEvents, Decl(dependentDestructuredVariables.ts, 386, 1))
warn: [message: string];
>warn : Symbol(ClientEvents.warn, Decl(dependentDestructuredVariables.ts, 390, 24))
shardDisconnect: [closeEvent: CloseEvent, shardId: number];
>shardDisconnect : Symbol(ClientEvents.shardDisconnect, Decl(dependentDestructuredVariables.ts, 391, 28))
>CloseEvent : Symbol(CloseEvent, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
}
declare class Client {
>Client : Symbol(Client, Decl(dependentDestructuredVariables.ts, 393, 1))
public on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void): void;
>on : Symbol(Client.on, Decl(dependentDestructuredVariables.ts, 395, 22))
>K : Symbol(K, Decl(dependentDestructuredVariables.ts, 396, 14))
>ClientEvents : Symbol(ClientEvents, Decl(dependentDestructuredVariables.ts, 386, 1))
>event : Symbol(event, Decl(dependentDestructuredVariables.ts, 396, 44))
>K : Symbol(K, Decl(dependentDestructuredVariables.ts, 396, 14))
>listener : Symbol(listener, Decl(dependentDestructuredVariables.ts, 396, 53))
>args : Symbol(args, Decl(dependentDestructuredVariables.ts, 396, 65))
>ClientEvents : Symbol(ClientEvents, Decl(dependentDestructuredVariables.ts, 386, 1))
>K : Symbol(K, Decl(dependentDestructuredVariables.ts, 396, 14))
}
const bot = new Client();
>bot : Symbol(bot, Decl(dependentDestructuredVariables.ts, 399, 5))
>Client : Symbol(Client, Decl(dependentDestructuredVariables.ts, 393, 1))
bot.on("shardDisconnect", (event, shard) => console.log(`Shard ${shard} disconnected (${event.code},${event.wasClean}): ${event.reason}`));
>bot.on : Symbol(Client.on, Decl(dependentDestructuredVariables.ts, 395, 22))
>bot : Symbol(bot, Decl(dependentDestructuredVariables.ts, 399, 5))
>on : Symbol(Client.on, Decl(dependentDestructuredVariables.ts, 395, 22))
>event : Symbol(event, Decl(dependentDestructuredVariables.ts, 400, 27))
>shard : Symbol(shard, Decl(dependentDestructuredVariables.ts, 400, 33))
>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, --, --))
>shard : Symbol(shard, Decl(dependentDestructuredVariables.ts, 400, 33))
>event.code : Symbol(CloseEvent.code, Decl(lib.dom.d.ts, --, --))
>event : Symbol(event, Decl(dependentDestructuredVariables.ts, 400, 27))
>code : Symbol(CloseEvent.code, Decl(lib.dom.d.ts, --, --))
>event.wasClean : Symbol(CloseEvent.wasClean, Decl(lib.dom.d.ts, --, --))
>event : Symbol(event, Decl(dependentDestructuredVariables.ts, 400, 27))
>wasClean : Symbol(CloseEvent.wasClean, Decl(lib.dom.d.ts, --, --))
>event.reason : Symbol(CloseEvent.reason, Decl(lib.dom.d.ts, --, --))
>event : Symbol(event, Decl(dependentDestructuredVariables.ts, 400, 27))
>reason : Symbol(CloseEvent.reason, Decl(lib.dom.d.ts, --, --))
bot.on("shardDisconnect", event => console.log(`${event.code} ${event.wasClean} ${event.reason}`));
>bot.on : Symbol(Client.on, Decl(dependentDestructuredVariables.ts, 395, 22))
>bot : Symbol(bot, Decl(dependentDestructuredVariables.ts, 399, 5))
>on : Symbol(Client.on, Decl(dependentDestructuredVariables.ts, 395, 22))
>event : Symbol(event, Decl(dependentDestructuredVariables.ts, 401, 25))
>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, --, --))
>event.code : Symbol(CloseEvent.code, Decl(lib.dom.d.ts, --, --))
>event : Symbol(event, Decl(dependentDestructuredVariables.ts, 401, 25))
>code : Symbol(CloseEvent.code, Decl(lib.dom.d.ts, --, --))
>event.wasClean : Symbol(CloseEvent.wasClean, Decl(lib.dom.d.ts, --, --))
>event : Symbol(event, Decl(dependentDestructuredVariables.ts, 401, 25))
>wasClean : Symbol(CloseEvent.wasClean, Decl(lib.dom.d.ts, --, --))
>event.reason : Symbol(CloseEvent.reason, Decl(lib.dom.d.ts, --, --))
>event : Symbol(event, Decl(dependentDestructuredVariables.ts, 401, 25))
>reason : Symbol(CloseEvent.reason, Decl(lib.dom.d.ts, --, --))
@@ -1115,3 +1115,76 @@ const fa3: (...args: [true, number] | [false, string]) => void = (guard, value)
}
}
// Repro from #52152
interface ClientEvents {
warn: [message: string];
>warn : [message: string]
shardDisconnect: [closeEvent: CloseEvent, shardId: number];
>shardDisconnect : [closeEvent: CloseEvent, shardId: number]
}
declare class Client {
>Client : Client
public on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void): void;
>on : <K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void) => void
>event : K
>listener : (...args: ClientEvents[K]) => void
>args : ClientEvents[K]
}
const bot = new Client();
>bot : Client
>new Client() : Client
>Client : typeof Client
bot.on("shardDisconnect", (event, shard) => console.log(`Shard ${shard} disconnected (${event.code},${event.wasClean}): ${event.reason}`));
>bot.on("shardDisconnect", (event, shard) => console.log(`Shard ${shard} disconnected (${event.code},${event.wasClean}): ${event.reason}`)) : void
>bot.on : <K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void) => void
>bot : Client
>on : <K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void) => void
>"shardDisconnect" : "shardDisconnect"
>(event, shard) => console.log(`Shard ${shard} disconnected (${event.code},${event.wasClean}): ${event.reason}`) : (event: CloseEvent, shard: number) => void
>event : CloseEvent
>shard : number
>console.log(`Shard ${shard} disconnected (${event.code},${event.wasClean}): ${event.reason}`) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
>`Shard ${shard} disconnected (${event.code},${event.wasClean}): ${event.reason}` : string
>shard : number
>event.code : number
>event : CloseEvent
>code : number
>event.wasClean : boolean
>event : CloseEvent
>wasClean : boolean
>event.reason : string
>event : CloseEvent
>reason : string
bot.on("shardDisconnect", event => console.log(`${event.code} ${event.wasClean} ${event.reason}`));
>bot.on("shardDisconnect", event => console.log(`${event.code} ${event.wasClean} ${event.reason}`)) : void
>bot.on : <K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void) => void
>bot : Client
>on : <K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void) => void
>"shardDisconnect" : "shardDisconnect"
>event => console.log(`${event.code} ${event.wasClean} ${event.reason}`) : (event: CloseEvent) => void
>event : CloseEvent
>console.log(`${event.code} ${event.wasClean} ${event.reason}`) : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
>`${event.code} ${event.wasClean} ${event.reason}` : string
>event.code : number
>event : CloseEvent
>code : number
>event.wasClean : boolean
>event : CloseEvent
>wasClean : boolean
>event.reason : string
>event : CloseEvent
>reason : string
@@ -390,3 +390,18 @@ const fa3: (...args: [true, number] | [false, string]) => void = (guard, value)
}
}
}
// Repro from #52152
interface ClientEvents {
warn: [message: string];
shardDisconnect: [closeEvent: CloseEvent, shardId: number];
}
declare class Client {
public on<K extends keyof ClientEvents>(event: K, listener: (...args: ClientEvents[K]) => void): void;
}
const bot = new Client();
bot.on("shardDisconnect", (event, shard) => console.log(`Shard ${shard} disconnected (${event.code},${event.wasClean}): ${event.reason}`));
bot.on("shardDisconnect", event => console.log(`${event.code} ${event.wasClean} ${event.reason}`));