mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 21:53:42 -06:00
Merge branch 'master' into inferToUnionTypes
This commit is contained in:
commit
ce6c04e9b5
@ -12693,10 +12693,11 @@ namespace ts {
|
||||
else if (source.flags & TypeFlags.Conditional) {
|
||||
if (target.flags & TypeFlags.Conditional) {
|
||||
// Two conditional types 'T1 extends U1 ? X1 : Y1' and 'T2 extends U2 ? X2 : Y2' are related if
|
||||
// one of T1 and T2 is related to the other, U1 and U2 are identical types, X1 is related to X2,
|
||||
// and Y1 is related to Y2.
|
||||
if (isTypeIdenticalTo((<ConditionalType>source).extendsType, (<ConditionalType>target).extendsType) &&
|
||||
(isRelatedTo((<ConditionalType>source).checkType, (<ConditionalType>target).checkType) || isRelatedTo((<ConditionalType>target).checkType, (<ConditionalType>source).checkType))) {
|
||||
// they have the same distributivity, T1 and T2 are identical types, U1 and U2 are identical
|
||||
// types, X1 is related to X2, and Y1 is related to Y2.
|
||||
if ((<ConditionalType>source).root.isDistributive === (<ConditionalType>target).root.isDistributive &&
|
||||
isTypeIdenticalTo((<ConditionalType>source).extendsType, (<ConditionalType>target).extendsType) &&
|
||||
isTypeIdenticalTo((<ConditionalType>source).checkType, (<ConditionalType>target).checkType)) {
|
||||
if (result = isRelatedTo(getTrueTypeFromConditionalType(<ConditionalType>source), getTrueTypeFromConditionalType(<ConditionalType>target), reportErrors)) {
|
||||
result &= isRelatedTo(getFalseTypeFromConditionalType(<ConditionalType>source), getFalseTypeFromConditionalType(<ConditionalType>target), reportErrors);
|
||||
}
|
||||
@ -21539,13 +21540,8 @@ namespace ts {
|
||||
}
|
||||
if (signature.hasRestParameter) {
|
||||
const restType = getTypeOfSymbol(signature.parameters[paramCount]);
|
||||
if (isTupleType(restType)) {
|
||||
if (pos - paramCount < getLengthOfTupleType(restType)) {
|
||||
return restType.typeArguments![pos - paramCount];
|
||||
}
|
||||
return getRestTypeOfTupleType(restType);
|
||||
}
|
||||
return getIndexTypeOfType(restType, IndexKind.Number);
|
||||
const indexType = getLiteralType(pos - paramCount);
|
||||
return getIndexedAccessType(restType, indexType);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
@ -21553,18 +21549,22 @@ namespace ts {
|
||||
function getRestTypeAtPosition(source: Signature, pos: number): Type {
|
||||
const paramCount = getParameterCount(source);
|
||||
const restType = getEffectiveRestType(source);
|
||||
if (restType && pos === paramCount - 1) {
|
||||
const nonRestCount = paramCount - (restType ? 1 : 0);
|
||||
if (restType && pos === nonRestCount) {
|
||||
return restType;
|
||||
}
|
||||
const start = restType ? Math.min(pos, paramCount - 1) : pos;
|
||||
const types = [];
|
||||
const names = [];
|
||||
for (let i = start; i < paramCount; i++) {
|
||||
for (let i = pos; i < nonRestCount; i++) {
|
||||
types.push(getTypeAtPosition(source, i));
|
||||
names.push(getParameterNameAtPosition(source, i));
|
||||
}
|
||||
if (restType) {
|
||||
types.push(getIndexedAccessType(restType, numberType));
|
||||
names.push(getParameterNameAtPosition(source, nonRestCount));
|
||||
}
|
||||
const minArgumentCount = getMinArgumentCount(source);
|
||||
const minLength = minArgumentCount < start ? 0 : minArgumentCount - start;
|
||||
const minLength = minArgumentCount < pos ? 0 : minArgumentCount - pos;
|
||||
return createTupleType(types, minLength, !!restType, /*readonly*/ false, names);
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,6 @@ namespace ts.server {
|
||||
export const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground";
|
||||
export const ProjectLoadingStartEvent = "projectLoadingStart";
|
||||
export const ProjectLoadingFinishEvent = "projectLoadingFinish";
|
||||
export const SurveyReady = "surveyReady";
|
||||
export const LargeFileReferencedEvent = "largeFileReferenced";
|
||||
export const ConfigFileDiagEvent = "configFileDiag";
|
||||
export const ProjectLanguageServiceStateEvent = "projectLanguageServiceState";
|
||||
@ -30,11 +29,6 @@ namespace ts.server {
|
||||
data: { project: Project; };
|
||||
}
|
||||
|
||||
export interface SurveyReady {
|
||||
eventName: typeof SurveyReady;
|
||||
data: { surveyId: string; };
|
||||
}
|
||||
|
||||
export interface LargeFileReferencedEvent {
|
||||
eventName: typeof LargeFileReferencedEvent;
|
||||
data: { file: string; fileSize: number; maxFileSize: number; };
|
||||
@ -146,7 +140,6 @@ namespace ts.server {
|
||||
}
|
||||
|
||||
export type ProjectServiceEvent = LargeFileReferencedEvent |
|
||||
SurveyReady |
|
||||
ProjectsUpdatedInBackgroundEvent |
|
||||
ProjectLoadingStartEvent |
|
||||
ProjectLoadingFinishEvent |
|
||||
@ -518,9 +511,6 @@ namespace ts.server {
|
||||
/** Tracks projects that we have already sent telemetry for. */
|
||||
private readonly seenProjects = createMap<true>();
|
||||
|
||||
/** Tracks projects that we have already sent survey events for. */
|
||||
private readonly seenSurveyProjects = createMap<true>();
|
||||
|
||||
/*@internal*/
|
||||
readonly watchFactory: WatchFactory<WatchType, Project>;
|
||||
|
||||
@ -722,14 +712,6 @@ namespace ts.server {
|
||||
this.eventHandler(event);
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
sendSurveyReadyEvent(surveyId: string) {
|
||||
if (!this.eventHandler) {
|
||||
return;
|
||||
}
|
||||
this.eventHandler({ eventName: SurveyReady, data: { surveyId } });
|
||||
}
|
||||
|
||||
/* @internal */
|
||||
sendLargeFileReferencedEvent(file: string, fileSize: number) {
|
||||
if (!this.eventHandler) {
|
||||
@ -1611,20 +1593,6 @@ namespace ts.server {
|
||||
return project;
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
sendSurveyReady(project: ExternalProject | ConfiguredProject): void {
|
||||
if (this.seenSurveyProjects.has(project.projectName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (project.getCompilerOptions().checkJs !== undefined) {
|
||||
const name = "checkJs";
|
||||
this.logger.info(`Survey ${name} is ready`);
|
||||
this.sendSurveyReadyEvent(name);
|
||||
this.seenSurveyProjects.set(project.projectName, true);
|
||||
}
|
||||
}
|
||||
|
||||
/*@internal*/
|
||||
sendProjectTelemetry(project: ExternalProject | ConfiguredProject): void {
|
||||
if (this.seenProjects.has(project.projectName)) {
|
||||
|
||||
@ -1431,7 +1431,6 @@ namespace ts.server {
|
||||
}
|
||||
this.projectService.sendProjectLoadingFinishEvent(this);
|
||||
this.projectService.sendProjectTelemetry(this);
|
||||
this.projectService.sendSurveyReady(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1627,7 +1626,6 @@ namespace ts.server {
|
||||
updateGraph() {
|
||||
const result = super.updateGraph();
|
||||
this.projectService.sendProjectTelemetry(this);
|
||||
this.projectService.sendSurveyReady(this);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@ -610,10 +610,6 @@ namespace ts.server {
|
||||
diagnostics: bakedDiags
|
||||
}, ConfigFileDiagEvent);
|
||||
break;
|
||||
case SurveyReady:
|
||||
const { surveyId } = event.data;
|
||||
this.event<protocol.SurveyReadyEventBody>({ surveyId }, SurveyReady);
|
||||
break;
|
||||
case ProjectLanguageServiceStateEvent: {
|
||||
const eventName: protocol.ProjectLanguageServiceStateEventName = ProjectLanguageServiceStateEvent;
|
||||
this.event<protocol.ProjectLanguageServiceStateEventBody>({
|
||||
|
||||
@ -109,7 +109,6 @@
|
||||
"unittests/tsserver/events/projectLanguageServiceState.ts",
|
||||
"unittests/tsserver/events/projectLoading.ts",
|
||||
"unittests/tsserver/events/projectUpdatedInBackground.ts",
|
||||
"unittests/tsserver/events/surveyReady.ts",
|
||||
"unittests/tsserver/externalProjects.ts",
|
||||
"unittests/tsserver/forceConsistentCasingInFileNames.ts",
|
||||
"unittests/tsserver/formatSettings.ts",
|
||||
|
||||
@ -1,111 +0,0 @@
|
||||
namespace ts.projectSystem {
|
||||
describe("unittests:: tsserver:: events:: SurveyReady", () => {
|
||||
function createSessionWithEventHandler(host: TestServerHost) {
|
||||
const { session, events: surveyEvents } = createSessionWithEventTracking<server.SurveyReady>(host, server.SurveyReady);
|
||||
|
||||
return { session, verifySurveyReadyEvent };
|
||||
|
||||
function verifySurveyReadyEvent(numberOfEvents: number) {
|
||||
assert.equal(surveyEvents.length, numberOfEvents);
|
||||
const expectedEvents = numberOfEvents === 0 ? [] : [{
|
||||
eventName: server.SurveyReady,
|
||||
data: { surveyId: "checkJs" }
|
||||
}];
|
||||
assert.deepEqual(surveyEvents, expectedEvents);
|
||||
}
|
||||
}
|
||||
|
||||
it("doesn't log an event when checkJs isn't set", () => {
|
||||
const projectRoot = "/user/username/projects/project";
|
||||
const file: File = {
|
||||
path: `${projectRoot}/src/file.ts`,
|
||||
content: "export var y = 10;"
|
||||
};
|
||||
const tsconfig: File = {
|
||||
path: `${projectRoot}/tsconfig.json`,
|
||||
content: JSON.stringify({ compilerOptions: {} }),
|
||||
};
|
||||
const host = createServerHost([file, tsconfig]);
|
||||
const { session, verifySurveyReadyEvent } = createSessionWithEventHandler(host);
|
||||
const service = session.getProjectService();
|
||||
openFilesForSession([file], session);
|
||||
checkNumberOfProjects(service, { configuredProjects: 1 });
|
||||
const project = service.configuredProjects.get(tsconfig.path)!;
|
||||
checkProjectActualFiles(project, [file.path, tsconfig.path]);
|
||||
|
||||
verifySurveyReadyEvent(0);
|
||||
});
|
||||
|
||||
it("logs an event when checkJs is set", () => {
|
||||
const projectRoot = "/user/username/projects/project";
|
||||
const file: File = {
|
||||
path: `${projectRoot}/src/file.ts`,
|
||||
content: "export var y = 10;"
|
||||
};
|
||||
const tsconfig: File = {
|
||||
path: `${projectRoot}/tsconfig.json`,
|
||||
content: JSON.stringify({ compilerOptions: { checkJs: true } }),
|
||||
};
|
||||
const host = createServerHost([file, tsconfig]);
|
||||
const { session, verifySurveyReadyEvent } = createSessionWithEventHandler(host);
|
||||
openFilesForSession([file], session);
|
||||
|
||||
verifySurveyReadyEvent(1);
|
||||
});
|
||||
|
||||
it("logs an event when checkJs is set, only the first time", () => {
|
||||
const projectRoot = "/user/username/projects/project";
|
||||
const file: File = {
|
||||
path: `${projectRoot}/src/file.ts`,
|
||||
content: "export var y = 10;"
|
||||
};
|
||||
const rando: File = {
|
||||
path: `/rando/calrissian.ts`,
|
||||
content: "export function f() { }"
|
||||
};
|
||||
const tsconfig: File = {
|
||||
path: `${projectRoot}/tsconfig.json`,
|
||||
content: JSON.stringify({ compilerOptions: { checkJs: true } }),
|
||||
};
|
||||
const host = createServerHost([file, tsconfig]);
|
||||
const { session, verifySurveyReadyEvent } = createSessionWithEventHandler(host);
|
||||
openFilesForSession([file], session);
|
||||
|
||||
verifySurveyReadyEvent(1);
|
||||
|
||||
closeFilesForSession([file], session);
|
||||
openFilesForSession([rando], session);
|
||||
openFilesForSession([file], session);
|
||||
|
||||
verifySurveyReadyEvent(1);
|
||||
});
|
||||
|
||||
it("logs an event when checkJs is set after closing and reopening", () => {
|
||||
const projectRoot = "/user/username/projects/project";
|
||||
const file: File = {
|
||||
path: `${projectRoot}/src/file.ts`,
|
||||
content: "export var y = 10;"
|
||||
};
|
||||
const rando: File = {
|
||||
path: `/rando/calrissian.ts`,
|
||||
content: "export function f() { }"
|
||||
};
|
||||
const tsconfig: File = {
|
||||
path: `${projectRoot}/tsconfig.json`,
|
||||
content: JSON.stringify({}),
|
||||
};
|
||||
const host = createServerHost([file, tsconfig]);
|
||||
const { session, verifySurveyReadyEvent } = createSessionWithEventHandler(host);
|
||||
openFilesForSession([file], session);
|
||||
|
||||
verifySurveyReadyEvent(0);
|
||||
|
||||
closeFilesForSession([file], session);
|
||||
openFilesForSession([rando], session);
|
||||
host.writeFile(tsconfig.path, JSON.stringify({ compilerOptions: { checkJs: true } }));
|
||||
openFilesForSession([file], session);
|
||||
|
||||
verifySurveyReadyEvent(1);
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -8357,7 +8357,6 @@ declare namespace ts.server {
|
||||
const ProjectsUpdatedInBackgroundEvent = "projectsUpdatedInBackground";
|
||||
const ProjectLoadingStartEvent = "projectLoadingStart";
|
||||
const ProjectLoadingFinishEvent = "projectLoadingFinish";
|
||||
const SurveyReady = "surveyReady";
|
||||
const LargeFileReferencedEvent = "largeFileReferenced";
|
||||
const ConfigFileDiagEvent = "configFileDiag";
|
||||
const ProjectLanguageServiceStateEvent = "projectLanguageServiceState";
|
||||
@ -8382,12 +8381,6 @@ declare namespace ts.server {
|
||||
project: Project;
|
||||
};
|
||||
}
|
||||
interface SurveyReady {
|
||||
eventName: typeof SurveyReady;
|
||||
data: {
|
||||
surveyId: string;
|
||||
};
|
||||
}
|
||||
interface LargeFileReferencedEvent {
|
||||
eventName: typeof LargeFileReferencedEvent;
|
||||
data: {
|
||||
@ -8472,7 +8465,7 @@ declare namespace ts.server {
|
||||
interface OpenFileInfo {
|
||||
readonly checkJs: boolean;
|
||||
}
|
||||
type ProjectServiceEvent = LargeFileReferencedEvent | SurveyReady | ProjectsUpdatedInBackgroundEvent | ProjectLoadingStartEvent | ProjectLoadingFinishEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
|
||||
type ProjectServiceEvent = LargeFileReferencedEvent | ProjectsUpdatedInBackgroundEvent | ProjectLoadingStartEvent | ProjectLoadingFinishEvent | ConfigFileDiagEvent | ProjectLanguageServiceStateEvent | ProjectInfoTelemetryEvent | OpenFileInfoTelemetryEvent;
|
||||
type ProjectServiceEventHandler = (event: ProjectServiceEvent) => void;
|
||||
interface SafeList {
|
||||
[name: string]: {
|
||||
@ -8589,8 +8582,6 @@ declare namespace ts.server {
|
||||
readonly syntaxOnly?: boolean;
|
||||
/** Tracks projects that we have already sent telemetry for. */
|
||||
private readonly seenProjects;
|
||||
/** Tracks projects that we have already sent survey events for. */
|
||||
private readonly seenSurveyProjects;
|
||||
constructor(opts: ProjectServiceOptions);
|
||||
toPath(fileName: string): Path;
|
||||
private loadTypesMap;
|
||||
|
||||
@ -1,29 +1,38 @@
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(15,5): error TS2322: Type 'Covariant<A>' is not assignable to type 'Covariant<B>'.
|
||||
Type 'A' is not assignable to type 'B'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(19,5): error TS2322: Type 'Contravariant<B>' is not assignable to type 'Contravariant<A>'.
|
||||
Type 'A' is not assignable to type 'B'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(24,5): error TS2322: Type 'Invariant<B>' is not assignable to type 'Invariant<A>'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(16,5): error TS2322: Type 'Covariant<B>' is not assignable to type 'Covariant<A>'.
|
||||
Types of property 'foo' are incompatible.
|
||||
Type 'B extends string ? B : number' is not assignable to type 'A extends string ? A : number'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(17,5): error TS2322: Type 'Covariant<A>' is not assignable to type 'Covariant<B>'.
|
||||
Types of property 'foo' are incompatible.
|
||||
Type 'A extends string ? A : number' is not assignable to type 'B extends string ? B : number'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(21,5): error TS2322: Type 'Contravariant<B>' is not assignable to type 'Contravariant<A>'.
|
||||
Types of property 'foo' are incompatible.
|
||||
Type 'B extends string ? keyof B : number' is not assignable to type 'A extends string ? keyof A : number'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(22,5): error TS2322: Type 'Contravariant<A>' is not assignable to type 'Contravariant<B>'.
|
||||
Types of property 'foo' are incompatible.
|
||||
Type 'A extends string ? keyof A : number' is not assignable to type 'B extends string ? keyof B : number'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(26,5): error TS2322: Type 'Invariant<B>' is not assignable to type 'Invariant<A>'.
|
||||
Types of property 'foo' are incompatible.
|
||||
Type 'B extends string ? keyof B : B' is not assignable to type 'A extends string ? keyof A : A'.
|
||||
Type 'keyof B' is not assignable to type 'keyof A'.
|
||||
Type 'string | number | symbol' is not assignable to type 'keyof A'.
|
||||
Type 'string' is not assignable to type 'keyof A'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(25,5): error TS2322: Type 'Invariant<A>' is not assignable to type 'Invariant<B>'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(27,5): error TS2322: Type 'Invariant<A>' is not assignable to type 'Invariant<B>'.
|
||||
Types of property 'foo' are incompatible.
|
||||
Type 'A extends string ? keyof A : A' is not assignable to type 'B extends string ? keyof B : B'.
|
||||
Type 'A' is not assignable to type 'B'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(73,12): error TS2345: Argument of type 'Extract<Extract<T, Foo>, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2345: Argument of type 'Extract<Extract<T, Foo>, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
|
||||
Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
|
||||
Type 'Extract<Foo & T, Bar>' is not assignable to type '{ foo: string; bat: string; }'.
|
||||
Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(74,12): error TS2345: Argument of type 'Extract<T, Foo & Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(76,12): error TS2345: Argument of type 'Extract<T, Foo & Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
|
||||
Property 'bat' is missing in type 'Foo & Bar' but required in type '{ foo: string; bat: string; }'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2345: Argument of type 'Extract2<T, Foo, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(77,12): error TS2345: Argument of type 'Extract2<T, Foo, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
|
||||
Type 'T extends Bar ? T : never' is not assignable to type '{ foo: string; bat: string; }'.
|
||||
Type 'Bar & Foo & T' is not assignable to type '{ foo: string; bat: string; }'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(165,5): error TS2322: Type 'MyElement<A>' is not assignable to type 'MyElement<B>'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(170,5): error TS2322: Type 'MyAcceptor<B>' is not assignable to type 'MyAcceptor<A>'.
|
||||
tests/cases/conformance/types/conditional/conditionalTypes2.ts(177,5): error TS2322: Type 'Dist<T>' is not assignable to type 'Aux<{ a: T; }>'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/conditional/conditionalTypes2.ts (7 errors) ====
|
||||
==== tests/cases/conformance/types/conditional/conditionalTypes2.ts (12 errors) ====
|
||||
// #27118: Conditional types are now invariant in the check type.
|
||||
|
||||
interface Covariant<T> {
|
||||
foo: T extends string ? T : number;
|
||||
}
|
||||
@ -37,19 +46,29 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
|
||||
}
|
||||
|
||||
function f1<A, B extends A>(a: Covariant<A>, b: Covariant<B>) {
|
||||
a = b;
|
||||
a = b; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'Covariant<B>' is not assignable to type 'Covariant<A>'.
|
||||
!!! error TS2322: Types of property 'foo' are incompatible.
|
||||
!!! error TS2322: Type 'B extends string ? B : number' is not assignable to type 'A extends string ? A : number'.
|
||||
b = a; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'Covariant<A>' is not assignable to type 'Covariant<B>'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
!!! error TS2322: Types of property 'foo' are incompatible.
|
||||
!!! error TS2322: Type 'A extends string ? A : number' is not assignable to type 'B extends string ? B : number'.
|
||||
}
|
||||
|
||||
function f2<A, B extends A>(a: Contravariant<A>, b: Contravariant<B>) {
|
||||
a = b; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'Contravariant<B>' is not assignable to type 'Contravariant<A>'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
b = a;
|
||||
!!! error TS2322: Types of property 'foo' are incompatible.
|
||||
!!! error TS2322: Type 'B extends string ? keyof B : number' is not assignable to type 'A extends string ? keyof A : number'.
|
||||
b = a; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'Contravariant<A>' is not assignable to type 'Contravariant<B>'.
|
||||
!!! error TS2322: Types of property 'foo' are incompatible.
|
||||
!!! error TS2322: Type 'A extends string ? keyof A : number' is not assignable to type 'B extends string ? keyof B : number'.
|
||||
}
|
||||
|
||||
function f3<A, B extends A>(a: Invariant<A>, b: Invariant<B>) {
|
||||
@ -58,15 +77,11 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
|
||||
!!! error TS2322: Type 'Invariant<B>' is not assignable to type 'Invariant<A>'.
|
||||
!!! error TS2322: Types of property 'foo' are incompatible.
|
||||
!!! error TS2322: Type 'B extends string ? keyof B : B' is not assignable to type 'A extends string ? keyof A : A'.
|
||||
!!! error TS2322: Type 'keyof B' is not assignable to type 'keyof A'.
|
||||
!!! error TS2322: Type 'string | number | symbol' is not assignable to type 'keyof A'.
|
||||
!!! error TS2322: Type 'string' is not assignable to type 'keyof A'.
|
||||
b = a; // Error
|
||||
~
|
||||
!!! error TS2322: Type 'Invariant<A>' is not assignable to type 'Invariant<B>'.
|
||||
!!! error TS2322: Types of property 'foo' are incompatible.
|
||||
!!! error TS2322: Type 'A extends string ? keyof A : A' is not assignable to type 'B extends string ? keyof B : B'.
|
||||
!!! error TS2322: Type 'A' is not assignable to type 'B'.
|
||||
}
|
||||
|
||||
// Extract<T, Function> is a T that is known to be a Function
|
||||
@ -120,13 +135,13 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
|
||||
!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
|
||||
!!! error TS2345: Type 'Extract<Foo & T, Bar>' is not assignable to type '{ foo: string; bat: string; }'.
|
||||
!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
|
||||
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here.
|
||||
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here.
|
||||
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:64:43: 'bat' is declared here.
|
||||
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:64:43: 'bat' is declared here.
|
||||
fooBat(y); // Error
|
||||
~
|
||||
!!! error TS2345: Argument of type 'Extract<T, Foo & Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
|
||||
!!! error TS2345: Property 'bat' is missing in type 'Foo & Bar' but required in type '{ foo: string; bat: string; }'.
|
||||
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here.
|
||||
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:64:43: 'bat' is declared here.
|
||||
fooBat(z); // Error
|
||||
~
|
||||
!!! error TS2345: Argument of type 'Extract2<T, Foo, Bar>' is not assignable to parameter of type '{ foo: string; bat: string; }'.
|
||||
@ -134,38 +149,6 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
|
||||
!!! error TS2345: Type 'Bar & Foo & T' is not assignable to type '{ foo: string; bat: string; }'.
|
||||
}
|
||||
|
||||
// Repros from #22860
|
||||
|
||||
class Opt<T> {
|
||||
toVector(): Vector<T> {
|
||||
return <any>undefined;
|
||||
}
|
||||
}
|
||||
|
||||
interface Seq<T> {
|
||||
tail(): Opt<Seq<T>>;
|
||||
}
|
||||
|
||||
class Vector<T> implements Seq<T> {
|
||||
tail(): Opt<Vector<T>> {
|
||||
return <any>undefined;
|
||||
}
|
||||
partition2<U extends T>(predicate:(v:T)=>v is U): [Vector<U>,Vector<Exclude<T, U>>];
|
||||
partition2(predicate:(x:T)=>boolean): [Vector<T>,Vector<T>];
|
||||
partition2<U extends T>(predicate:(v:T)=>boolean): [Vector<U>,Vector<any>] {
|
||||
return <any>undefined;
|
||||
}
|
||||
}
|
||||
|
||||
interface A1<T> {
|
||||
bat: B1<A1<T>>;
|
||||
}
|
||||
|
||||
interface B1<T> extends A1<T> {
|
||||
bat: B1<B1<T>>;
|
||||
boom: T extends any ? true : true
|
||||
}
|
||||
|
||||
// Repro from #22899
|
||||
|
||||
declare function toString1(value: object | Function): string ;
|
||||
@ -246,4 +229,29 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
|
||||
};
|
||||
type PCCA = ProductComplementComplement['a'];
|
||||
type PCCB = ProductComplementComplement['b'];
|
||||
|
||||
// Repros from #27118
|
||||
|
||||
type MyElement<A> = [A] extends [[infer E]] ? E : never;
|
||||
function oops<A, B extends A>(arg: MyElement<A>): MyElement<B> {
|
||||
return arg; // Unsound, should be error
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'MyElement<A>' is not assignable to type 'MyElement<B>'.
|
||||
}
|
||||
|
||||
type MyAcceptor<A> = [A] extends [[infer E]] ? (arg: E) => void : never;
|
||||
function oops2<A, B extends A>(arg: MyAcceptor<B>): MyAcceptor<A> {
|
||||
return arg; // Unsound, should be error
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'MyAcceptor<B>' is not assignable to type 'MyAcceptor<A>'.
|
||||
}
|
||||
|
||||
type Dist<T> = T extends number ? number : string;
|
||||
type Aux<A extends { a: unknown }> = A["a"] extends number ? number : string;
|
||||
type Nondist<T> = Aux<{a: T}>;
|
||||
function oops3<T>(arg: Dist<T>): Nondist<T> {
|
||||
return arg; // Unsound, should be error
|
||||
~~~~~~~~~~~
|
||||
!!! error TS2322: Type 'Dist<T>' is not assignable to type 'Aux<{ a: T; }>'.
|
||||
}
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
//// [conditionalTypes2.ts]
|
||||
// #27118: Conditional types are now invariant in the check type.
|
||||
|
||||
interface Covariant<T> {
|
||||
foo: T extends string ? T : number;
|
||||
}
|
||||
@ -12,13 +14,13 @@ interface Invariant<T> {
|
||||
}
|
||||
|
||||
function f1<A, B extends A>(a: Covariant<A>, b: Covariant<B>) {
|
||||
a = b;
|
||||
a = b; // Error
|
||||
b = a; // Error
|
||||
}
|
||||
|
||||
function f2<A, B extends A>(a: Contravariant<A>, b: Contravariant<B>) {
|
||||
a = b; // Error
|
||||
b = a;
|
||||
b = a; // Error
|
||||
}
|
||||
|
||||
function f3<A, B extends A>(a: Invariant<A>, b: Invariant<B>) {
|
||||
@ -76,38 +78,6 @@ function f21<T>(x: Extract<Extract<T, Foo>, Bar>, y: Extract<T, Foo & Bar>, z: E
|
||||
fooBat(z); // Error
|
||||
}
|
||||
|
||||
// Repros from #22860
|
||||
|
||||
class Opt<T> {
|
||||
toVector(): Vector<T> {
|
||||
return <any>undefined;
|
||||
}
|
||||
}
|
||||
|
||||
interface Seq<T> {
|
||||
tail(): Opt<Seq<T>>;
|
||||
}
|
||||
|
||||
class Vector<T> implements Seq<T> {
|
||||
tail(): Opt<Vector<T>> {
|
||||
return <any>undefined;
|
||||
}
|
||||
partition2<U extends T>(predicate:(v:T)=>v is U): [Vector<U>,Vector<Exclude<T, U>>];
|
||||
partition2(predicate:(x:T)=>boolean): [Vector<T>,Vector<T>];
|
||||
partition2<U extends T>(predicate:(v:T)=>boolean): [Vector<U>,Vector<any>] {
|
||||
return <any>undefined;
|
||||
}
|
||||
}
|
||||
|
||||
interface A1<T> {
|
||||
bat: B1<A1<T>>;
|
||||
}
|
||||
|
||||
interface B1<T> extends A1<T> {
|
||||
bat: B1<B1<T>>;
|
||||
boom: T extends any ? true : true
|
||||
}
|
||||
|
||||
// Repro from #22899
|
||||
|
||||
declare function toString1(value: object | Function): string ;
|
||||
@ -188,17 +158,37 @@ type ProductComplementComplement = {
|
||||
};
|
||||
type PCCA = ProductComplementComplement['a'];
|
||||
type PCCB = ProductComplementComplement['b'];
|
||||
|
||||
// Repros from #27118
|
||||
|
||||
type MyElement<A> = [A] extends [[infer E]] ? E : never;
|
||||
function oops<A, B extends A>(arg: MyElement<A>): MyElement<B> {
|
||||
return arg; // Unsound, should be error
|
||||
}
|
||||
|
||||
type MyAcceptor<A> = [A] extends [[infer E]] ? (arg: E) => void : never;
|
||||
function oops2<A, B extends A>(arg: MyAcceptor<B>): MyAcceptor<A> {
|
||||
return arg; // Unsound, should be error
|
||||
}
|
||||
|
||||
type Dist<T> = T extends number ? number : string;
|
||||
type Aux<A extends { a: unknown }> = A["a"] extends number ? number : string;
|
||||
type Nondist<T> = Aux<{a: T}>;
|
||||
function oops3<T>(arg: Dist<T>): Nondist<T> {
|
||||
return arg; // Unsound, should be error
|
||||
}
|
||||
|
||||
|
||||
//// [conditionalTypes2.js]
|
||||
"use strict";
|
||||
// #27118: Conditional types are now invariant in the check type.
|
||||
function f1(a, b) {
|
||||
a = b;
|
||||
a = b; // Error
|
||||
b = a; // Error
|
||||
}
|
||||
function f2(a, b) {
|
||||
a = b; // Error
|
||||
b = a;
|
||||
b = a; // Error
|
||||
}
|
||||
function f3(a, b) {
|
||||
a = b; // Error
|
||||
@ -239,32 +229,21 @@ function f21(x, y, z) {
|
||||
fooBat(y); // Error
|
||||
fooBat(z); // Error
|
||||
}
|
||||
// Repros from #22860
|
||||
var Opt = /** @class */ (function () {
|
||||
function Opt() {
|
||||
}
|
||||
Opt.prototype.toVector = function () {
|
||||
return undefined;
|
||||
};
|
||||
return Opt;
|
||||
}());
|
||||
var Vector = /** @class */ (function () {
|
||||
function Vector() {
|
||||
}
|
||||
Vector.prototype.tail = function () {
|
||||
return undefined;
|
||||
};
|
||||
Vector.prototype.partition2 = function (predicate) {
|
||||
return undefined;
|
||||
};
|
||||
return Vector;
|
||||
}());
|
||||
function foo(value) {
|
||||
if (isFunction(value)) {
|
||||
toString1(value);
|
||||
toString2(value);
|
||||
}
|
||||
}
|
||||
function oops(arg) {
|
||||
return arg; // Unsound, should be error
|
||||
}
|
||||
function oops2(arg) {
|
||||
return arg; // Unsound, should be error
|
||||
}
|
||||
function oops3(arg) {
|
||||
return arg; // Unsound, should be error
|
||||
}
|
||||
|
||||
|
||||
//// [conditionalTypes2.d.ts]
|
||||
@ -302,24 +281,6 @@ declare function fooBat(x: {
|
||||
declare type Extract2<T, U, V> = T extends U ? T extends V ? T : never : never;
|
||||
declare function f20<T>(x: Extract<Extract<T, Foo>, Bar>, y: Extract<T, Foo & Bar>, z: Extract2<T, Foo, Bar>): void;
|
||||
declare function f21<T>(x: Extract<Extract<T, Foo>, Bar>, y: Extract<T, Foo & Bar>, z: Extract2<T, Foo, Bar>): void;
|
||||
declare class Opt<T> {
|
||||
toVector(): Vector<T>;
|
||||
}
|
||||
interface Seq<T> {
|
||||
tail(): Opt<Seq<T>>;
|
||||
}
|
||||
declare class Vector<T> implements Seq<T> {
|
||||
tail(): Opt<Vector<T>>;
|
||||
partition2<U extends T>(predicate: (v: T) => v is U): [Vector<U>, Vector<Exclude<T, U>>];
|
||||
partition2(predicate: (x: T) => boolean): [Vector<T>, Vector<T>];
|
||||
}
|
||||
interface A1<T> {
|
||||
bat: B1<A1<T>>;
|
||||
}
|
||||
interface B1<T> extends A1<T> {
|
||||
bat: B1<B1<T>>;
|
||||
boom: T extends any ? true : true;
|
||||
}
|
||||
declare function toString1(value: object | Function): string;
|
||||
declare function toString2(value: Function): string;
|
||||
declare function foo<T>(value: T): void;
|
||||
@ -392,3 +353,15 @@ declare type ProductComplementComplement = {
|
||||
};
|
||||
declare type PCCA = ProductComplementComplement['a'];
|
||||
declare type PCCB = ProductComplementComplement['b'];
|
||||
declare type MyElement<A> = [A] extends [[infer E]] ? E : never;
|
||||
declare function oops<A, B extends A>(arg: MyElement<A>): MyElement<B>;
|
||||
declare type MyAcceptor<A> = [A] extends [[infer E]] ? (arg: E) => void : never;
|
||||
declare function oops2<A, B extends A>(arg: MyAcceptor<B>): MyAcceptor<A>;
|
||||
declare type Dist<T> = T extends number ? number : string;
|
||||
declare type Aux<A extends {
|
||||
a: unknown;
|
||||
}> = A["a"] extends number ? number : string;
|
||||
declare type Nondist<T> = Aux<{
|
||||
a: T;
|
||||
}>;
|
||||
declare function oops3<T>(arg: Dist<T>): Nondist<T>;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,6 @@
|
||||
=== tests/cases/conformance/types/conditional/conditionalTypes2.ts ===
|
||||
// #27118: Conditional types are now invariant in the check type.
|
||||
|
||||
interface Covariant<T> {
|
||||
foo: T extends string ? T : number;
|
||||
>foo : T extends string ? T : number
|
||||
@ -19,7 +21,7 @@ function f1<A, B extends A>(a: Covariant<A>, b: Covariant<B>) {
|
||||
>a : Covariant<A>
|
||||
>b : Covariant<B>
|
||||
|
||||
a = b;
|
||||
a = b; // Error
|
||||
>a = b : Covariant<B>
|
||||
>a : Covariant<A>
|
||||
>b : Covariant<B>
|
||||
@ -40,7 +42,7 @@ function f2<A, B extends A>(a: Contravariant<A>, b: Contravariant<B>) {
|
||||
>a : Contravariant<A>
|
||||
>b : Contravariant<B>
|
||||
|
||||
b = a;
|
||||
b = a; // Error
|
||||
>b = a : Contravariant<A>
|
||||
>b : Contravariant<B>
|
||||
>a : Contravariant<A>
|
||||
@ -207,71 +209,6 @@ function f21<T>(x: Extract<Extract<T, Foo>, Bar>, y: Extract<T, Foo & Bar>, z: E
|
||||
>z : Extract2<T, Foo, Bar>
|
||||
}
|
||||
|
||||
// Repros from #22860
|
||||
|
||||
class Opt<T> {
|
||||
>Opt : Opt<T>
|
||||
|
||||
toVector(): Vector<T> {
|
||||
>toVector : () => Vector<T>
|
||||
|
||||
return <any>undefined;
|
||||
><any>undefined : any
|
||||
>undefined : undefined
|
||||
}
|
||||
}
|
||||
|
||||
interface Seq<T> {
|
||||
tail(): Opt<Seq<T>>;
|
||||
>tail : () => Opt<Seq<T>>
|
||||
}
|
||||
|
||||
class Vector<T> implements Seq<T> {
|
||||
>Vector : Vector<T>
|
||||
|
||||
tail(): Opt<Vector<T>> {
|
||||
>tail : () => Opt<Vector<T>>
|
||||
|
||||
return <any>undefined;
|
||||
><any>undefined : any
|
||||
>undefined : undefined
|
||||
}
|
||||
partition2<U extends T>(predicate:(v:T)=>v is U): [Vector<U>,Vector<Exclude<T, U>>];
|
||||
>partition2 : { <U extends T>(predicate: (v: T) => v is U): [Vector<U>, Vector<Exclude<T, U>>]; (predicate: (x: T) => boolean): [Vector<T>, Vector<T>]; }
|
||||
>predicate : (v: T) => v is U
|
||||
>v : T
|
||||
|
||||
partition2(predicate:(x:T)=>boolean): [Vector<T>,Vector<T>];
|
||||
>partition2 : { <U extends T>(predicate: (v: T) => v is U): [Vector<U>, Vector<Exclude<T, U>>]; (predicate: (x: T) => boolean): [Vector<T>, Vector<T>]; }
|
||||
>predicate : (x: T) => boolean
|
||||
>x : T
|
||||
|
||||
partition2<U extends T>(predicate:(v:T)=>boolean): [Vector<U>,Vector<any>] {
|
||||
>partition2 : { <U extends T>(predicate: (v: T) => v is U): [Vector<U>, Vector<Exclude<T, U>>]; (predicate: (x: T) => boolean): [Vector<T>, Vector<T>]; }
|
||||
>predicate : (v: T) => boolean
|
||||
>v : T
|
||||
|
||||
return <any>undefined;
|
||||
><any>undefined : any
|
||||
>undefined : undefined
|
||||
}
|
||||
}
|
||||
|
||||
interface A1<T> {
|
||||
bat: B1<A1<T>>;
|
||||
>bat : B1<A1<T>>
|
||||
}
|
||||
|
||||
interface B1<T> extends A1<T> {
|
||||
bat: B1<B1<T>>;
|
||||
>bat : B1<B1<T>>
|
||||
|
||||
boom: T extends any ? true : true
|
||||
>boom : T extends any ? true : true
|
||||
>true : true
|
||||
>true : true
|
||||
}
|
||||
|
||||
// Repro from #22899
|
||||
|
||||
declare function toString1(value: object | Function): string ;
|
||||
@ -431,3 +368,47 @@ type PCCA = ProductComplementComplement['a'];
|
||||
type PCCB = ProductComplementComplement['b'];
|
||||
>PCCB : Product<"b", 1>
|
||||
|
||||
// Repros from #27118
|
||||
|
||||
type MyElement<A> = [A] extends [[infer E]] ? E : never;
|
||||
>MyElement : MyElement<A>
|
||||
|
||||
function oops<A, B extends A>(arg: MyElement<A>): MyElement<B> {
|
||||
>oops : <A, B extends A>(arg: MyElement<A>) => MyElement<B>
|
||||
>arg : MyElement<A>
|
||||
|
||||
return arg; // Unsound, should be error
|
||||
>arg : MyElement<A>
|
||||
}
|
||||
|
||||
type MyAcceptor<A> = [A] extends [[infer E]] ? (arg: E) => void : never;
|
||||
>MyAcceptor : MyAcceptor<A>
|
||||
>arg : E
|
||||
|
||||
function oops2<A, B extends A>(arg: MyAcceptor<B>): MyAcceptor<A> {
|
||||
>oops2 : <A, B extends A>(arg: MyAcceptor<B>) => MyAcceptor<A>
|
||||
>arg : MyAcceptor<B>
|
||||
|
||||
return arg; // Unsound, should be error
|
||||
>arg : MyAcceptor<B>
|
||||
}
|
||||
|
||||
type Dist<T> = T extends number ? number : string;
|
||||
>Dist : Dist<T>
|
||||
|
||||
type Aux<A extends { a: unknown }> = A["a"] extends number ? number : string;
|
||||
>Aux : Aux<A>
|
||||
>a : unknown
|
||||
|
||||
type Nondist<T> = Aux<{a: T}>;
|
||||
>Nondist : Aux<{ a: T; }>
|
||||
>a : T
|
||||
|
||||
function oops3<T>(arg: Dist<T>): Nondist<T> {
|
||||
>oops3 : <T>(arg: Dist<T>) => Aux<{ a: T; }>
|
||||
>arg : Dist<T>
|
||||
|
||||
return arg; // Unsound, should be error
|
||||
>arg : Dist<T>
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error TS2345: Argument of type '(a: number, b: any, ...x: any[]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'.
|
||||
tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error TS2345: Argument of type '(a: number, b: T[0], ...x: T[number][]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'.
|
||||
Types of parameters 'b' and 'args' are incompatible.
|
||||
Type 'T' is not assignable to type '[any, ...any[]]'.
|
||||
Property '0' is missing in type 'any[]' but required in type '[any, ...any[]]'.
|
||||
Type 'T' is not assignable to type '[T[0], ...T[number][]]'.
|
||||
Property '0' is missing in type 'any[]' but required in type '[T[0], ...T[number][]]'.
|
||||
|
||||
|
||||
==== tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts (1 errors) ====
|
||||
@ -62,10 +62,10 @@ tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error
|
||||
f((a, ...x) => {});
|
||||
f((a, b, ...x) => {});
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS2345: Argument of type '(a: number, b: any, ...x: any[]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'.
|
||||
!!! error TS2345: Argument of type '(a: number, b: T[0], ...x: T[number][]) => void' is not assignable to parameter of type '(x: number, ...args: T) => void'.
|
||||
!!! error TS2345: Types of parameters 'b' and 'args' are incompatible.
|
||||
!!! error TS2345: Type 'T' is not assignable to type '[any, ...any[]]'.
|
||||
!!! error TS2345: Property '0' is missing in type 'any[]' but required in type '[any, ...any[]]'.
|
||||
!!! error TS2345: Type 'T' is not assignable to type '[T[0], ...T[number][]]'.
|
||||
!!! error TS2345: Property '0' is missing in type 'any[]' but required in type '[T[0], ...T[number][]]'.
|
||||
}
|
||||
|
||||
// Repro from #25288
|
||||
@ -79,4 +79,18 @@ tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts(56,7): error
|
||||
|
||||
(function foo(...rest){}(1, ''));
|
||||
take(function(...rest){});
|
||||
|
||||
// Repro from #29833
|
||||
|
||||
type ArgsUnion = [number, string] | [number, Error];
|
||||
type TupleUnionFunc = (...params: ArgsUnion) => number;
|
||||
|
||||
const funcUnionTupleNoRest: TupleUnionFunc = (num, strOrErr) => {
|
||||
return num;
|
||||
};
|
||||
|
||||
const funcUnionTupleRest: TupleUnionFunc = (...params) => {
|
||||
const [num, strOrErr] = params;
|
||||
return num;
|
||||
};
|
||||
|
||||
@ -68,6 +68,20 @@ declare function take(cb: (a: number, b: string) => void): void;
|
||||
|
||||
(function foo(...rest){}(1, ''));
|
||||
take(function(...rest){});
|
||||
|
||||
// Repro from #29833
|
||||
|
||||
type ArgsUnion = [number, string] | [number, Error];
|
||||
type TupleUnionFunc = (...params: ArgsUnion) => number;
|
||||
|
||||
const funcUnionTupleNoRest: TupleUnionFunc = (num, strOrErr) => {
|
||||
return num;
|
||||
};
|
||||
|
||||
const funcUnionTupleRest: TupleUnionFunc = (...params) => {
|
||||
const [num, strOrErr] = params;
|
||||
return num;
|
||||
};
|
||||
|
||||
|
||||
//// [restTuplesFromContextualTypes.js]
|
||||
@ -274,6 +288,17 @@ take(function () {
|
||||
rest[_i] = arguments[_i];
|
||||
}
|
||||
});
|
||||
var funcUnionTupleNoRest = function (num, strOrErr) {
|
||||
return num;
|
||||
};
|
||||
var funcUnionTupleRest = function () {
|
||||
var params = [];
|
||||
for (var _i = 0; _i < arguments.length; _i++) {
|
||||
params[_i] = arguments[_i];
|
||||
}
|
||||
var num = params[0], strOrErr = params[1];
|
||||
return num;
|
||||
};
|
||||
|
||||
|
||||
//// [restTuplesFromContextualTypes.d.ts]
|
||||
@ -286,3 +311,7 @@ declare function f3(cb: (x: number, ...args: typeof t3) => void): void;
|
||||
declare function f4<T extends any[]>(t: T): void;
|
||||
declare var tuple: [number, string];
|
||||
declare function take(cb: (a: number, b: string) => void): void;
|
||||
declare type ArgsUnion = [number, string] | [number, Error];
|
||||
declare type TupleUnionFunc = (...params: ArgsUnion) => number;
|
||||
declare const funcUnionTupleNoRest: TupleUnionFunc;
|
||||
declare const funcUnionTupleRest: TupleUnionFunc;
|
||||
|
||||
@ -265,3 +265,40 @@ take(function(...rest){});
|
||||
>take : Symbol(take, Decl(restTuplesFromContextualTypes.ts, 61, 33))
|
||||
>rest : Symbol(rest, Decl(restTuplesFromContextualTypes.ts, 68, 14))
|
||||
|
||||
// Repro from #29833
|
||||
|
||||
type ArgsUnion = [number, string] | [number, Error];
|
||||
>ArgsUnion : Symbol(ArgsUnion, Decl(restTuplesFromContextualTypes.ts, 68, 26))
|
||||
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
|
||||
|
||||
type TupleUnionFunc = (...params: ArgsUnion) => number;
|
||||
>TupleUnionFunc : Symbol(TupleUnionFunc, Decl(restTuplesFromContextualTypes.ts, 72, 52))
|
||||
>params : Symbol(params, Decl(restTuplesFromContextualTypes.ts, 73, 23))
|
||||
>ArgsUnion : Symbol(ArgsUnion, Decl(restTuplesFromContextualTypes.ts, 68, 26))
|
||||
|
||||
const funcUnionTupleNoRest: TupleUnionFunc = (num, strOrErr) => {
|
||||
>funcUnionTupleNoRest : Symbol(funcUnionTupleNoRest, Decl(restTuplesFromContextualTypes.ts, 75, 5))
|
||||
>TupleUnionFunc : Symbol(TupleUnionFunc, Decl(restTuplesFromContextualTypes.ts, 72, 52))
|
||||
>num : Symbol(num, Decl(restTuplesFromContextualTypes.ts, 75, 46))
|
||||
>strOrErr : Symbol(strOrErr, Decl(restTuplesFromContextualTypes.ts, 75, 50))
|
||||
|
||||
return num;
|
||||
>num : Symbol(num, Decl(restTuplesFromContextualTypes.ts, 75, 46))
|
||||
|
||||
};
|
||||
|
||||
const funcUnionTupleRest: TupleUnionFunc = (...params) => {
|
||||
>funcUnionTupleRest : Symbol(funcUnionTupleRest, Decl(restTuplesFromContextualTypes.ts, 79, 5))
|
||||
>TupleUnionFunc : Symbol(TupleUnionFunc, Decl(restTuplesFromContextualTypes.ts, 72, 52))
|
||||
>params : Symbol(params, Decl(restTuplesFromContextualTypes.ts, 79, 44))
|
||||
|
||||
const [num, strOrErr] = params;
|
||||
>num : Symbol(num, Decl(restTuplesFromContextualTypes.ts, 80, 9))
|
||||
>strOrErr : Symbol(strOrErr, Decl(restTuplesFromContextualTypes.ts, 80, 13))
|
||||
>params : Symbol(params, Decl(restTuplesFromContextualTypes.ts, 79, 44))
|
||||
|
||||
return num;
|
||||
>num : Symbol(num, Decl(restTuplesFromContextualTypes.ts, 80, 9))
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -332,8 +332,8 @@ function f4<T extends any[]>(t: T) {
|
||||
f((...x) => {});
|
||||
>f((...x) => {}) : void
|
||||
>f : (cb: (x: number, ...args: T) => void) => void
|
||||
>(...x) => {} : (x: number, ...args: any[]) => void
|
||||
>x : [number, ...any[]]
|
||||
>(...x) => {} : (x: number, ...args: T[number][]) => void
|
||||
>x : [number, ...T[number][]]
|
||||
|
||||
f((a, ...x) => {});
|
||||
>f((a, ...x) => {}) : void
|
||||
@ -345,10 +345,10 @@ function f4<T extends any[]>(t: T) {
|
||||
f((a, b, ...x) => {});
|
||||
>f((a, b, ...x) => {}) : void
|
||||
>f : (cb: (x: number, ...args: T) => void) => void
|
||||
>(a, b, ...x) => {} : (a: number, b: any, ...x: any[]) => void
|
||||
>(a, b, ...x) => {} : (a: number, b: T[0], ...x: T[number][]) => void
|
||||
>a : number
|
||||
>b : any
|
||||
>x : any[]
|
||||
>b : T[0]
|
||||
>x : T[number][]
|
||||
}
|
||||
|
||||
// Repro from #25288
|
||||
@ -389,3 +389,38 @@ take(function(...rest){});
|
||||
>function(...rest){} : (a: number, b: string) => void
|
||||
>rest : [number, string]
|
||||
|
||||
// Repro from #29833
|
||||
|
||||
type ArgsUnion = [number, string] | [number, Error];
|
||||
>ArgsUnion : ArgsUnion
|
||||
|
||||
type TupleUnionFunc = (...params: ArgsUnion) => number;
|
||||
>TupleUnionFunc : TupleUnionFunc
|
||||
>params : ArgsUnion
|
||||
|
||||
const funcUnionTupleNoRest: TupleUnionFunc = (num, strOrErr) => {
|
||||
>funcUnionTupleNoRest : TupleUnionFunc
|
||||
>(num, strOrErr) => { return num;} : (num: number, strOrErr: string | Error) => number
|
||||
>num : number
|
||||
>strOrErr : string | Error
|
||||
|
||||
return num;
|
||||
>num : number
|
||||
|
||||
};
|
||||
|
||||
const funcUnionTupleRest: TupleUnionFunc = (...params) => {
|
||||
>funcUnionTupleRest : TupleUnionFunc
|
||||
>(...params) => { const [num, strOrErr] = params; return num;} : (...params: ArgsUnion) => number
|
||||
>params : ArgsUnion
|
||||
|
||||
const [num, strOrErr] = params;
|
||||
>num : number
|
||||
>strOrErr : string | Error
|
||||
>params : ArgsUnion
|
||||
|
||||
return num;
|
||||
>num : number
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
// @strict: true
|
||||
// @declaration: true
|
||||
|
||||
// #27118: Conditional types are now invariant in the check type.
|
||||
|
||||
interface Covariant<T> {
|
||||
foo: T extends string ? T : number;
|
||||
}
|
||||
@ -14,13 +16,13 @@ interface Invariant<T> {
|
||||
}
|
||||
|
||||
function f1<A, B extends A>(a: Covariant<A>, b: Covariant<B>) {
|
||||
a = b;
|
||||
a = b; // Error
|
||||
b = a; // Error
|
||||
}
|
||||
|
||||
function f2<A, B extends A>(a: Contravariant<A>, b: Contravariant<B>) {
|
||||
a = b; // Error
|
||||
b = a;
|
||||
b = a; // Error
|
||||
}
|
||||
|
||||
function f3<A, B extends A>(a: Invariant<A>, b: Invariant<B>) {
|
||||
@ -78,38 +80,6 @@ function f21<T>(x: Extract<Extract<T, Foo>, Bar>, y: Extract<T, Foo & Bar>, z: E
|
||||
fooBat(z); // Error
|
||||
}
|
||||
|
||||
// Repros from #22860
|
||||
|
||||
class Opt<T> {
|
||||
toVector(): Vector<T> {
|
||||
return <any>undefined;
|
||||
}
|
||||
}
|
||||
|
||||
interface Seq<T> {
|
||||
tail(): Opt<Seq<T>>;
|
||||
}
|
||||
|
||||
class Vector<T> implements Seq<T> {
|
||||
tail(): Opt<Vector<T>> {
|
||||
return <any>undefined;
|
||||
}
|
||||
partition2<U extends T>(predicate:(v:T)=>v is U): [Vector<U>,Vector<Exclude<T, U>>];
|
||||
partition2(predicate:(x:T)=>boolean): [Vector<T>,Vector<T>];
|
||||
partition2<U extends T>(predicate:(v:T)=>boolean): [Vector<U>,Vector<any>] {
|
||||
return <any>undefined;
|
||||
}
|
||||
}
|
||||
|
||||
interface A1<T> {
|
||||
bat: B1<A1<T>>;
|
||||
}
|
||||
|
||||
interface B1<T> extends A1<T> {
|
||||
bat: B1<B1<T>>;
|
||||
boom: T extends any ? true : true
|
||||
}
|
||||
|
||||
// Repro from #22899
|
||||
|
||||
declare function toString1(value: object | Function): string ;
|
||||
@ -190,3 +160,22 @@ type ProductComplementComplement = {
|
||||
};
|
||||
type PCCA = ProductComplementComplement['a'];
|
||||
type PCCB = ProductComplementComplement['b'];
|
||||
|
||||
// Repros from #27118
|
||||
|
||||
type MyElement<A> = [A] extends [[infer E]] ? E : never;
|
||||
function oops<A, B extends A>(arg: MyElement<A>): MyElement<B> {
|
||||
return arg; // Unsound, should be error
|
||||
}
|
||||
|
||||
type MyAcceptor<A> = [A] extends [[infer E]] ? (arg: E) => void : never;
|
||||
function oops2<A, B extends A>(arg: MyAcceptor<B>): MyAcceptor<A> {
|
||||
return arg; // Unsound, should be error
|
||||
}
|
||||
|
||||
type Dist<T> = T extends number ? number : string;
|
||||
type Aux<A extends { a: unknown }> = A["a"] extends number ? number : string;
|
||||
type Nondist<T> = Aux<{a: T}>;
|
||||
function oops3<T>(arg: Dist<T>): Nondist<T> {
|
||||
return arg; // Unsound, should be error
|
||||
}
|
||||
|
||||
@ -70,3 +70,17 @@ declare function take(cb: (a: number, b: string) => void): void;
|
||||
|
||||
(function foo(...rest){}(1, ''));
|
||||
take(function(...rest){});
|
||||
|
||||
// Repro from #29833
|
||||
|
||||
type ArgsUnion = [number, string] | [number, Error];
|
||||
type TupleUnionFunc = (...params: ArgsUnion) => number;
|
||||
|
||||
const funcUnionTupleNoRest: TupleUnionFunc = (num, strOrErr) => {
|
||||
return num;
|
||||
};
|
||||
|
||||
const funcUnionTupleRest: TupleUnionFunc = (...params) => {
|
||||
const [num, strOrErr] = params;
|
||||
return num;
|
||||
};
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 40bdb4eadabc9fbed7d83e3f26817a931c0763b6
|
||||
Subproject commit 6b9706810b55af326a93b9aa59cb17815a30bb32
|
||||
@ -1 +1 @@
|
||||
Subproject commit 67f1c4877ee1090b66d468a847caccca411a6f82
|
||||
Subproject commit 6e0de0812231c3a48387d398d092418749aa39f1
|
||||
@ -1 +1 @@
|
||||
Subproject commit 10282ea20648b465caec6448849f24fc34e1ba3e
|
||||
Subproject commit a28f44f613276446fb764dec7fab38b7cff8a07c
|
||||
Loading…
x
Reference in New Issue
Block a user