Skip to content
Permalink
Browse files
make RegExpExecArray always include index 0 (#50713)
* make `RegExpExecArray` always include index 0

* update baseline

* remove `BaseRegExpArray` interface

* add test

Co-authored-by: DetachHead <detachhead@users.noreply.github.com>
  • Loading branch information
DetachHead and DetachHead committed Sep 16, 2022
1 parent 01cae69 commit 2970c5d1671b2376711cd55594c4597d6da7d8c3
Show file tree
Hide file tree
Showing 31 changed files with 671 additions and 43 deletions.
@@ -940,6 +940,10 @@ interface RegExpExecArray extends Array<string> {
* A copy of the search string.
*/
input: string;
/**
* The first match. This will always be present because `null` will be returned if there are no matches.
*/
0: string;
}

interface RegExp {
@@ -41,7 +41,7 @@ tests/cases/conformance/es6/destructuring/destructuringParameterDeclaration4.ts(
a1(...array2); // Error parameter type is (number|string)[]
~~~~~~
!!! error TS2552: Cannot find name 'array2'. Did you mean 'Array'?
!!! related TS2728 /.ts/lib.es5.d.ts:1490:13: 'Array' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1494:13: 'Array' is declared here.
a5([1, 2, "string", false, true]); // Error, parameter type is [any, any, [[any]]]
~~~~~~~~
!!! error TS2322: Type 'string' is not assignable to type '[[any]]'.
@@ -33,8 +33,8 @@ tests/cases/compiler/destructuringTuple.ts(11,60): error TS2769: No overload mat
!!! error TS2769: Overload 2 of 3, '(callbackfn: (previousValue: [], currentValue: number, currentIndex: number, array: number[]) => [], initialValue: []): []', gave the following error.
!!! error TS2769: Type 'never[]' is not assignable to type '[]'.
!!! error TS2769: Target allows only 0 element(s) but source may have more.
!!! related TS6502 /.ts/lib.es5.d.ts:1455:24: The expected type comes from the return type of this signature.
!!! related TS6502 /.ts/lib.es5.d.ts:1461:27: The expected type comes from the return type of this signature.
!!! related TS6502 /.ts/lib.es5.d.ts:1459:24: The expected type comes from the return type of this signature.
!!! related TS6502 /.ts/lib.es5.d.ts:1465:27: The expected type comes from the return type of this signature.
~~
!!! error TS2769: No overload matches this call.
!!! error TS2769: Overload 1 of 2, '(...items: ConcatArray<never>[]): never[]', gave the following error.
@@ -11,7 +11,7 @@ tests/cases/conformance/types/members/duplicateNumericIndexers.ts(25,5): error T
tests/cases/conformance/types/members/duplicateNumericIndexers.ts(29,5): error TS2374: Duplicate index signature for type 'number'.
tests/cases/conformance/types/members/duplicateNumericIndexers.ts(30,5): error TS2374: Duplicate index signature for type 'number'.
lib.es5.d.ts(517,5): error TS2374: Duplicate index signature for type 'number'.
lib.es5.d.ts(1476,5): error TS2374: Duplicate index signature for type 'number'.
lib.es5.d.ts(1480,5): error TS2374: Duplicate index signature for type 'number'.


==== tests/cases/conformance/types/members/duplicateNumericIndexers.ts (12 errors) ====
@@ -7,5 +7,5 @@ tests/cases/compiler/mappedTypeWithAsClauseAndLateBoundProperty.ts(3,1): error T
tgt2 = src2; // Should error
~~~~
!!! error TS2741: Property 'length' is missing in type '{ [x: number]: number; toString: () => string; toLocaleString: () => string; pop: () => number; push: (...items: number[]) => number; concat: { (...items: ConcatArray<number>[]): number[]; (...items: (number | ConcatArray<number>)[]): number[]; }; join: (separator?: string) => string; reverse: () => number[]; shift: () => number; slice: (start?: number, end?: number) => number[]; sort: (compareFn?: (a: number, b: number) => number) => number[]; splice: { (start: number, deleteCount?: number): number[]; (start: number, deleteCount: number, ...items: number[]): number[]; }; unshift: (...items: number[]) => number; indexOf: (searchElement: number, fromIndex?: number) => number; lastIndexOf: (searchElement: number, fromIndex?: number) => number; every: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; }; some: (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any) => boolean; forEach: (callbackfn: (value: number, index: number, array: number[]) => void, thisArg?: any) => void; map: <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]; filter: { <S extends number>(predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): number[]; }; reduce: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }; reduceRight: { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; <U>(callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; }; find: { <S extends number>(predicate: (this: void, value: number, index: number, obj: number[]) => value is S, thisArg?: any): S; (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any): number; }; findIndex: (predicate: (value: number, index: number, obj: number[]) => unknown, thisArg?: any) => number; fill: (value: number, start?: number, end?: number) => number[]; copyWithin: (target: number, start: number, end?: number) => number[]; entries: () => IterableIterator<[number, number]>; keys: () => IterableIterator<number>; values: () => IterableIterator<number>; includes: (searchElement: number, fromIndex?: number) => boolean; flatMap: <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]; flat: <A, D extends number = 1>(this: A, depth?: D) => FlatArray<A, D>[]; [iterator]: () => IterableIterator<number>; [unscopables]: () => { copyWithin: boolean; entries: boolean; fill: boolean; find: boolean; findIndex: boolean; keys: boolean; values: boolean; }; }' but required in type 'number[]'.
!!! related TS2728 /.ts/lib.es5.d.ts:1299:5: 'length' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1303:5: 'length' is declared here.

@@ -24,7 +24,7 @@ tests/cases/conformance/types/any/narrowExceptionVariableInCatchClause.ts(16,17)
err.massage; // ERROR: Property 'massage' does not exist on type 'Error'
~~~~~~~
!!! error TS2551: Property 'massage' does not exist on type 'Error'. Did you mean 'message'?
!!! related TS2728 /.ts/lib.es5.d.ts:1049:5: 'message' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1053:5: 'message' is declared here.
}

else {
@@ -22,7 +22,7 @@ tests/cases/conformance/types/any/narrowFromAnyWithInstanceof.ts(22,7): error TS
x.mesage;
~~~~~~
!!! error TS2551: Property 'mesage' does not exist on type 'Error'. Did you mean 'message'?
!!! related TS2728 /.ts/lib.es5.d.ts:1049:5: 'message' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1053:5: 'message' is declared here.
}

if (x instanceof Date) {
@@ -41,7 +41,7 @@ tests/cases/conformance/types/any/narrowFromAnyWithTypePredicate.ts(33,7): error
x.mesage;
~~~~~~
!!! error TS2551: Property 'mesage' does not exist on type 'Error'. Did you mean 'message'?
!!! related TS2728 /.ts/lib.es5.d.ts:1049:5: 'message' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1053:5: 'message' is declared here.
}

if (isDate(x)) {
@@ -7,6 +7,6 @@ tests/cases/conformance/parser/ecmascript5/RegularExpressions/parserRegularExpre
/notregexp/a.foo();
~~~~~~~~~
!!! error TS2552: Cannot find name 'notregexp'. Did you mean 'RegExp'?
!!! related TS2728 /.ts/lib.es5.d.ts:1045:13: 'RegExp' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1049:13: 'RegExp' is declared here.
~
!!! error TS2304: Cannot find name 'a'.
@@ -6,6 +6,6 @@ tests/cases/conformance/parser/ecmascript5/RegularExpressions/parserRegularExpre
(1) /notregexp/a.foo();
~~~~~~~~~
!!! error TS2552: Cannot find name 'notregexp'. Did you mean 'RegExp'?
!!! related TS2728 /.ts/lib.es5.d.ts:1045:13: 'RegExp' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1049:13: 'RegExp' is declared here.
~
!!! error TS2304: Cannot find name 'a'.
@@ -19,7 +19,7 @@ tests/cases/conformance/parser/ecmascript5/parserS7.2_A1.5_T2.ts(20,3): error TS
$ERROR('#1: eval("\\u00A0var x\\u00A0= 1\\u00A0"); x === 1. Actual: ' + (x));
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}

//CHECK#2
@@ -28,7 +28,7 @@ tests/cases/conformance/parser/ecmascript5/parserS7.2_A1.5_T2.ts(20,3): error TS
$ERROR('#2:  var x = 1 ; x === 1. Actual: ' + (x));
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}


@@ -21,7 +21,7 @@ tests/cases/conformance/parser/ecmascript5/parserS7.3_A1.1_T2.ts(17,3): error TS
$ERROR('#1: var\\nx\\n=\\n1\\n; x === 1. Actual: ' + (x));
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}


@@ -50,70 +50,70 @@ tests/cases/conformance/parser/ecmascript5/parserS7.6_A4.2_T1.ts(142,3): error T
$ERROR('#А');
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
var \u0411 = 1;
if (Б !== 1) {
$ERROR('#Б');
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
var \u0412 = 1;
if (В !== 1) {
$ERROR('#В');
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
var \u0413 = 1;
if (Г !== 1) {
$ERROR('#Г');
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
var \u0414 = 1;
if (Д !== 1) {
$ERROR('#Д');
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
var \u0415 = 1;
if (Е !== 1) {
$ERROR('#Е');
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
var \u0416 = 1;
if (Ж !== 1) {
$ERROR('#Ж');
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
var \u0417 = 1;
if (З !== 1) {
$ERROR('#З');
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
var \u0418 = 1;
if (И !== 1) {
$ERROR('#И');
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
var \u0419 = 1;
if (Й !== 1) {
$ERROR('#Й');
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
var \u041A = 1;
if (К !== 1) {
@@ -11,13 +11,13 @@ tests/cases/conformance/parser/ecmascript5/parserUnicode1.ts(10,5): error TS2552
$ERROR('#6.1: var \\u0078x = 1; xx === 6. Actual: ' + (xx));
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.
}
}
catch (e) {
$ERROR('#6.2: var \\u0078x = 1; xx === 6. Actual: ' + (xx));
~~~~~~
!!! error TS2552: Cannot find name '$ERROR'. Did you mean 'Error'?
!!! related TS2728 /.ts/lib.es5.d.ts:1059:13: 'Error' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1063:13: 'Error' is declared here.

}
@@ -447,7 +447,7 @@ tests/cases/compiler/promisePermutations.ts(160,21): error TS2769: No overload m
!!! error TS2769: The last overload gave the following error.
!!! error TS2769: Argument of type '(x: any) => IPromise<string>' is not assignable to parameter of type '(error: any) => Promise<number>'.
!!! error TS2769: Property 'catch' is missing in type 'IPromise<string>' but required in type 'Promise<number>'.
!!! related TS2728 /.ts/lib.es5.d.ts:1535:5: 'catch' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1539:5: 'catch' is declared here.
!!! related TS2771 tests/cases/compiler/promisePermutations.ts:5:5: The last overload is declared here.
var s10g = s10.then(testFunctionP, nIPromise, sIPromise).then(sPromise, sIPromise, sIPromise); // ok

@@ -351,7 +351,7 @@ tests/cases/compiler/promisePermutations2.ts(159,21): error TS2345: Argument of
~~~~~~~~~
!!! error TS2345: Argument of type '(x: any) => IPromise<string>' is not assignable to parameter of type '(error: any) => Promise<number>'.
!!! error TS2345: Property 'catch' is missing in type 'IPromise<string>' but required in type 'Promise<number>'.
!!! related TS2728 /.ts/lib.es5.d.ts:1535:5: 'catch' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1539:5: 'catch' is declared here.
var s10g = s10.then(testFunctionP, nIPromise, sIPromise).then(sPromise, sIPromise, sIPromise); // ok

var r11: IPromise<number>;
@@ -398,7 +398,7 @@ tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of
!!! error TS2769: The last overload gave the following error.
!!! error TS2769: Argument of type '(x: any) => IPromise<string>' is not assignable to parameter of type '(error: any) => Promise<number>'.
!!! error TS2769: Property 'catch' is missing in type 'IPromise<string>' but required in type 'Promise<number>'.
!!! related TS2728 /.ts/lib.es5.d.ts:1535:5: 'catch' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1539:5: 'catch' is declared here.
!!! related TS2771 tests/cases/compiler/promisePermutations3.ts:7:5: The last overload is declared here.
var s10g = s10.then(testFunctionP, nIPromise, sIPromise).then(sPromise, sIPromise, sIPromise); // ok

@@ -445,5 +445,5 @@ tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of
~~~~~~~~~~~~~~~
!!! error TS2345: Argument of type '{ <T>(x: T): IPromise<T>; <T>(x: T, y: T): Promise<T>; }' is not assignable to parameter of type '(value: (x: any) => any) => Promise<unknown>'.
!!! error TS2345: Property 'catch' is missing in type 'IPromise<any>' but required in type 'Promise<unknown>'.
!!! related TS2728 /.ts/lib.es5.d.ts:1535:5: 'catch' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1539:5: 'catch' is declared here.
var s12c = s12.then(testFunction12P, testFunction12, testFunction12); // ok
@@ -5,4 +5,4 @@ tests/cases/compiler/redefineArray.ts(1,1): error TS2741: Property 'isArray' is
Array = function (n:number, s:string) {return n;};
~~~~~
!!! error TS2741: Property 'isArray' is missing in type '<T>(n: number, s: string) => number' but required in type 'ArrayConstructor'.
!!! related TS2728 /.ts/lib.es5.d.ts:1486:5: 'isArray' is declared here.
!!! related TS2728 /.ts/lib.es5.d.ts:1490:5: 'isArray' is declared here.
@@ -0,0 +1,28 @@
error TS5052: Option 'exactOptionalPropertyTypes' cannot be specified without specifying option 'strictNullChecks'.


!!! error TS5052: Option 'exactOptionalPropertyTypes' cannot be specified without specifying option 'strictNullChecks'.
==== tests/cases/compiler/regexpExecAndMatchTypeUsages.ts (0 errors) ====
export function foo(matchResult: RegExpExecArray, execResult: RegExpExecArray) {
matchResult[0].length;
matchResult[999].length;
matchResult.index + 0;
matchResult.input.length;
matchResult.groups["someVariable"].length;
matchResult.groups = undefined;

execResult[0].length;
execResult[999].length;
execResult.index + 0;
execResult.input.length;
execResult.groups["someVariable"].length;
execResult.groups = undefined;

if (Math.random()) {
matchResult = execResult;
}
else {
execResult = matchResult
}
}

@@ -0,0 +1,50 @@
//// [regexpExecAndMatchTypeUsages.ts]
export function foo(matchResult: RegExpExecArray, execResult: RegExpExecArray) {
matchResult[0].length;
matchResult[999].length;
matchResult.index + 0;
matchResult.input.length;
matchResult.groups["someVariable"].length;
matchResult.groups = undefined;

execResult[0].length;
execResult[999].length;
execResult.index + 0;
execResult.input.length;
execResult.groups["someVariable"].length;
execResult.groups = undefined;

if (Math.random()) {
matchResult = execResult;
}
else {
execResult = matchResult
}
}


//// [regexpExecAndMatchTypeUsages.js]
"use strict";
exports.__esModule = true;
exports.foo = void 0;
function foo(matchResult, execResult) {
matchResult[0].length;
matchResult[999].length;
matchResult.index + 0;
matchResult.input.length;
matchResult.groups["someVariable"].length;
matchResult.groups = undefined;
execResult[0].length;
execResult[999].length;
execResult.index + 0;
execResult.input.length;
execResult.groups["someVariable"].length;
execResult.groups = undefined;
if (Math.random()) {
matchResult = execResult;
}
else {
execResult = matchResult;
}
}
exports.foo = foo;

0 comments on commit 2970c5d

Please sign in to comment.