mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Better error message for unparenthesized function/constructor type notation in union/intersection types (#39570)
* add graceful error message for unparenthesized function types in union and intersection * add unparenthesizedFunctionTypeInUnionOrIntersection test * add unparenthesizedConstructorTypeInUnionOrIntersection test * Update src/compiler/parser.ts Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> * pass isInUnionType to parseFunctionOrConstructorTypeToError * Apply suggestions from code review Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com> * syntax fix * refactor isStartOfFunctionType into isStartOfFunctionTypeOrConstructorType * Update src/compiler/parser.ts Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> * hoist isUnionType Co-authored-by: Daniel Rosenwasser <DanielRosenwasser@users.noreply.github.com> Co-authored-by: Nathan Shively-Sanders <293473+sandersn@users.noreply.github.com>
This commit is contained in:
parent
37e6e2761c
commit
b6f09ccf06
@ -1164,6 +1164,22 @@
|
||||
"category": "Error",
|
||||
"code": 1384
|
||||
},
|
||||
"Function type notation must be parenthesized when used in a union type.": {
|
||||
"category": "Error",
|
||||
"code": 1385
|
||||
},
|
||||
"Constructor type notation must be parenthesized when used in a union type.": {
|
||||
"category": "Error",
|
||||
"code": 1386
|
||||
},
|
||||
"Function type notation must be parenthesized when used in an intersection type.": {
|
||||
"category": "Error",
|
||||
"code": 1387
|
||||
},
|
||||
"Constructor type notation must be parenthesized when used in an intersection type.": {
|
||||
"category": "Error",
|
||||
"code": 1388
|
||||
},
|
||||
|
||||
"The types of '{0}' are incompatible between these types.": {
|
||||
"category": "Error",
|
||||
|
||||
@ -3569,18 +3569,46 @@ namespace ts {
|
||||
return parsePostfixTypeOrHigher();
|
||||
}
|
||||
|
||||
function parseFunctionOrConstructorTypeToError(
|
||||
isInUnionType: boolean
|
||||
): TypeNode | undefined {
|
||||
// the function type and constructor type shorthand notation
|
||||
// are not allowed directly in unions and intersections, but we'll
|
||||
// try to parse them gracefully and issue a helpful message.
|
||||
if (isStartOfFunctionTypeOrConstructorType()) {
|
||||
const type = parseFunctionOrConstructorType();
|
||||
let diagnostic: DiagnosticMessage;
|
||||
if (isFunctionTypeNode(type)) {
|
||||
diagnostic = isInUnionType
|
||||
? Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_a_union_type
|
||||
: Diagnostics.Function_type_notation_must_be_parenthesized_when_used_in_an_intersection_type;
|
||||
}
|
||||
else {
|
||||
diagnostic = isInUnionType
|
||||
? Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_a_union_type
|
||||
: Diagnostics.Constructor_type_notation_must_be_parenthesized_when_used_in_an_intersection_type;
|
||||
|
||||
}
|
||||
parseErrorAtRange(type, diagnostic);
|
||||
return type;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseUnionOrIntersectionType(
|
||||
operator: SyntaxKind.BarToken | SyntaxKind.AmpersandToken,
|
||||
parseConstituentType: () => TypeNode,
|
||||
createTypeNode: (types: NodeArray<TypeNode>) => UnionOrIntersectionTypeNode
|
||||
): TypeNode {
|
||||
const pos = getNodePos();
|
||||
const isUnionType = operator === SyntaxKind.BarToken;
|
||||
const hasLeadingOperator = parseOptional(operator);
|
||||
let type = parseConstituentType();
|
||||
let type = hasLeadingOperator && parseFunctionOrConstructorTypeToError(isUnionType)
|
||||
|| parseConstituentType();
|
||||
if (token() === operator || hasLeadingOperator) {
|
||||
const types = [type];
|
||||
while (parseOptional(operator)) {
|
||||
types.push(parseConstituentType());
|
||||
types.push(parseFunctionOrConstructorTypeToError(isUnionType) || parseConstituentType());
|
||||
}
|
||||
type = finishNode(createTypeNode(createNodeArray(types, pos)), pos);
|
||||
}
|
||||
@ -3595,11 +3623,14 @@ namespace ts {
|
||||
return parseUnionOrIntersectionType(SyntaxKind.BarToken, parseIntersectionTypeOrHigher, factory.createUnionTypeNode);
|
||||
}
|
||||
|
||||
function isStartOfFunctionType(): boolean {
|
||||
function isStartOfFunctionTypeOrConstructorType(): boolean {
|
||||
if (token() === SyntaxKind.LessThanToken) {
|
||||
return true;
|
||||
}
|
||||
return token() === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType);
|
||||
if (token() === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType)) {
|
||||
return true;
|
||||
}
|
||||
return token() === SyntaxKind.NewKeyword;
|
||||
}
|
||||
|
||||
function skipParameterStart(): boolean {
|
||||
@ -3684,7 +3715,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function parseTypeWorker(noConditionalTypes?: boolean): TypeNode {
|
||||
if (isStartOfFunctionType() || token() === SyntaxKind.NewKeyword) {
|
||||
if (isStartOfFunctionTypeOrConstructorType()) {
|
||||
return parseFunctionOrConstructorType();
|
||||
}
|
||||
const pos = getNodePos();
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(1,19): error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(2,19): error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(3,12): error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(4,12): error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(5,19): error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(8,4): error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(11,19): error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(12,19): error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(13,12): error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(14,12): error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(15,19): error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(18,4): error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(20,37): error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(21,31): error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(22,16): error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts(22,41): error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
|
||||
|
||||
==== tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts (16 errors) ====
|
||||
type U1 = string | new () => void;
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
type U2 = string | new (foo: number) => void
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
type U3 = | new () => number
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
type U4 = | new (foo?: number) => void;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
type U5 = string | new (number: number, foo?: string) => void | number;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
type U6 =
|
||||
| string
|
||||
| new (...args: any[]) => void
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| number;
|
||||
~~~~~~~~~~
|
||||
!!! error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
|
||||
type I1 = string & new () => void;
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
type I2 = string & new (...foo: number[]) => void;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
type I3 = & new () => boolean
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
type I4 = & new () => boolean & null;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
type I5 = string & new (any: any, any2: any) => any & any;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
type I6 =
|
||||
& string
|
||||
& new (foo: any) => void;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
|
||||
type M1 = string | number & string | new () => number;
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
type M2 = any & string | any & new () => void;
|
||||
~~~~~~~~~~~~~~~
|
||||
!!! error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
type M3 = any & new (foo: any) => void | new () => void & any;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1388: Constructor type notation must be parenthesized when used in an intersection type.
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1386: Constructor type notation must be parenthesized when used in a union type.
|
||||
|
||||
type OK1 = string | (new ()=> void);
|
||||
type OK2 = string | (new ()=> string | number);
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
//// [unparenthesizedConstructorTypeInUnionOrIntersection.ts]
|
||||
type U1 = string | new () => void;
|
||||
type U2 = string | new (foo: number) => void
|
||||
type U3 = | new () => number
|
||||
type U4 = | new (foo?: number) => void;
|
||||
type U5 = string | new (number: number, foo?: string) => void | number;
|
||||
type U6 =
|
||||
| string
|
||||
| new (...args: any[]) => void
|
||||
| number;
|
||||
|
||||
type I1 = string & new () => void;
|
||||
type I2 = string & new (...foo: number[]) => void;
|
||||
type I3 = & new () => boolean
|
||||
type I4 = & new () => boolean & null;
|
||||
type I5 = string & new (any: any, any2: any) => any & any;
|
||||
type I6 =
|
||||
& string
|
||||
& new (foo: any) => void;
|
||||
|
||||
type M1 = string | number & string | new () => number;
|
||||
type M2 = any & string | any & new () => void;
|
||||
type M3 = any & new (foo: any) => void | new () => void & any;
|
||||
|
||||
type OK1 = string | (new ()=> void);
|
||||
type OK2 = string | (new ()=> string | number);
|
||||
|
||||
|
||||
//// [unparenthesizedConstructorTypeInUnionOrIntersection.js]
|
||||
@ -0,0 +1,70 @@
|
||||
=== tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts ===
|
||||
type U1 = string | new () => void;
|
||||
>U1 : Symbol(U1, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 0, 0))
|
||||
|
||||
type U2 = string | new (foo: number) => void
|
||||
>U2 : Symbol(U2, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 0, 34))
|
||||
>foo : Symbol(foo, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 1, 24))
|
||||
|
||||
type U3 = | new () => number
|
||||
>U3 : Symbol(U3, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 1, 44))
|
||||
|
||||
type U4 = | new (foo?: number) => void;
|
||||
>U4 : Symbol(U4, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 2, 28))
|
||||
>foo : Symbol(foo, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 3, 17))
|
||||
|
||||
type U5 = string | new (number: number, foo?: string) => void | number;
|
||||
>U5 : Symbol(U5, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 3, 39))
|
||||
>number : Symbol(number, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 4, 24))
|
||||
>foo : Symbol(foo, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 4, 39))
|
||||
|
||||
type U6 =
|
||||
>U6 : Symbol(U6, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 4, 71))
|
||||
|
||||
| string
|
||||
| new (...args: any[]) => void
|
||||
>args : Symbol(args, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 7, 9))
|
||||
|
||||
| number;
|
||||
|
||||
type I1 = string & new () => void;
|
||||
>I1 : Symbol(I1, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 8, 11))
|
||||
|
||||
type I2 = string & new (...foo: number[]) => void;
|
||||
>I2 : Symbol(I2, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 10, 34))
|
||||
>foo : Symbol(foo, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 11, 24))
|
||||
|
||||
type I3 = & new () => boolean
|
||||
>I3 : Symbol(I3, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 11, 50))
|
||||
|
||||
type I4 = & new () => boolean & null;
|
||||
>I4 : Symbol(I4, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 12, 29))
|
||||
|
||||
type I5 = string & new (any: any, any2: any) => any & any;
|
||||
>I5 : Symbol(I5, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 13, 37))
|
||||
>any : Symbol(any, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 14, 24))
|
||||
>any2 : Symbol(any2, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 14, 33))
|
||||
|
||||
type I6 =
|
||||
>I6 : Symbol(I6, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 14, 58))
|
||||
|
||||
& string
|
||||
& new (foo: any) => void;
|
||||
>foo : Symbol(foo, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 17, 9))
|
||||
|
||||
type M1 = string | number & string | new () => number;
|
||||
>M1 : Symbol(M1, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 17, 27))
|
||||
|
||||
type M2 = any & string | any & new () => void;
|
||||
>M2 : Symbol(M2, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 19, 54))
|
||||
|
||||
type M3 = any & new (foo: any) => void | new () => void & any;
|
||||
>M3 : Symbol(M3, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 20, 46))
|
||||
>foo : Symbol(foo, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 21, 21))
|
||||
|
||||
type OK1 = string | (new ()=> void);
|
||||
>OK1 : Symbol(OK1, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 21, 62))
|
||||
|
||||
type OK2 = string | (new ()=> string | number);
|
||||
>OK2 : Symbol(OK2, Decl(unparenthesizedConstructorTypeInUnionOrIntersection.ts, 23, 36))
|
||||
|
||||
@ -0,0 +1,71 @@
|
||||
=== tests/cases/compiler/unparenthesizedConstructorTypeInUnionOrIntersection.ts ===
|
||||
type U1 = string | new () => void;
|
||||
>U1 : U1
|
||||
|
||||
type U2 = string | new (foo: number) => void
|
||||
>U2 : U2
|
||||
>foo : number
|
||||
|
||||
type U3 = | new () => number
|
||||
>U3 : new () => number
|
||||
|
||||
type U4 = | new (foo?: number) => void;
|
||||
>U4 : new (foo?: number) => void
|
||||
>foo : number
|
||||
|
||||
type U5 = string | new (number: number, foo?: string) => void | number;
|
||||
>U5 : U5
|
||||
>number : number
|
||||
>foo : string
|
||||
|
||||
type U6 =
|
||||
>U6 : U6
|
||||
|
||||
| string
|
||||
| new (...args: any[]) => void
|
||||
>args : any[]
|
||||
|
||||
| number;
|
||||
|
||||
type I1 = string & new () => void;
|
||||
>I1 : I1
|
||||
|
||||
type I2 = string & new (...foo: number[]) => void;
|
||||
>I2 : I2
|
||||
>foo : number[]
|
||||
|
||||
type I3 = & new () => boolean
|
||||
>I3 : new () => boolean
|
||||
|
||||
type I4 = & new () => boolean & null;
|
||||
>I4 : new () => boolean & null
|
||||
>null : null
|
||||
|
||||
type I5 = string & new (any: any, any2: any) => any & any;
|
||||
>I5 : I5
|
||||
>any : any
|
||||
>any2 : any
|
||||
|
||||
type I6 =
|
||||
>I6 : I6
|
||||
|
||||
& string
|
||||
& new (foo: any) => void;
|
||||
>foo : any
|
||||
|
||||
type M1 = string | number & string | new () => number;
|
||||
>M1 : M1
|
||||
|
||||
type M2 = any & string | any & new () => void;
|
||||
>M2 : any
|
||||
|
||||
type M3 = any & new (foo: any) => void | new () => void & any;
|
||||
>M3 : any
|
||||
>foo : any
|
||||
|
||||
type OK1 = string | (new ()=> void);
|
||||
>OK1 : OK1
|
||||
|
||||
type OK2 = string | (new ()=> string | number);
|
||||
>OK2 : OK2
|
||||
|
||||
@ -0,0 +1,80 @@
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(1,19): error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(2,19): error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(3,12): error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(4,12): error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(5,19): error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(8,4): error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(11,19): error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(12,19): error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(13,12): error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(14,12): error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(15,19): error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(18,4): error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(20,37): error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(21,31): error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(22,16): error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts(22,37): error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
|
||||
|
||||
==== tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts (16 errors) ====
|
||||
type U1 = string | () => void;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
type U2 = string | (foo: number) => void
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
type U3 = | () => number
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
type U4 = | (foo?: number) => void;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
type U5 = string | (number: number, foo?: string) => void | number;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
type U6 =
|
||||
| string
|
||||
| (...args: any[]) => void
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
| number;
|
||||
~~~~~~~~~~
|
||||
!!! error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
|
||||
type I1 = string & () => void;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
type I2 = string & (...foo: number[]) => void;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
type I3 = & () => boolean
|
||||
~~~~~~~~~~~~~~
|
||||
!!! error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
type I4 = & () => boolean & null;
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
type I5 = string & (any: any, any2: any) => any & any;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
type I6 =
|
||||
& string
|
||||
& (foo: any) => void;
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
|
||||
type M1 = string | number & string | () => number;
|
||||
~~~~~~~~~~~~~
|
||||
!!! error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
type M2 = any & string | any & () => void;
|
||||
~~~~~~~~~~~
|
||||
!!! error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
type M3 = any & (foo: any) => void | () => void & any;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1387: Function type notation must be parenthesized when used in an intersection type.
|
||||
~~~~~~~~~~~~~~~~~
|
||||
!!! error TS1385: Function type notation must be parenthesized when used in a union type.
|
||||
|
||||
type OK1 = string | (number);
|
||||
type OK2 = string | ((number));
|
||||
type OK3 = string | (()=> void);
|
||||
type OK4 = string | (()=> string | number);
|
||||
|
||||
@ -0,0 +1,31 @@
|
||||
//// [unparenthesizedFunctionTypeInUnionOrIntersection.ts]
|
||||
type U1 = string | () => void;
|
||||
type U2 = string | (foo: number) => void
|
||||
type U3 = | () => number
|
||||
type U4 = | (foo?: number) => void;
|
||||
type U5 = string | (number: number, foo?: string) => void | number;
|
||||
type U6 =
|
||||
| string
|
||||
| (...args: any[]) => void
|
||||
| number;
|
||||
|
||||
type I1 = string & () => void;
|
||||
type I2 = string & (...foo: number[]) => void;
|
||||
type I3 = & () => boolean
|
||||
type I4 = & () => boolean & null;
|
||||
type I5 = string & (any: any, any2: any) => any & any;
|
||||
type I6 =
|
||||
& string
|
||||
& (foo: any) => void;
|
||||
|
||||
type M1 = string | number & string | () => number;
|
||||
type M2 = any & string | any & () => void;
|
||||
type M3 = any & (foo: any) => void | () => void & any;
|
||||
|
||||
type OK1 = string | (number);
|
||||
type OK2 = string | ((number));
|
||||
type OK3 = string | (()=> void);
|
||||
type OK4 = string | (()=> string | number);
|
||||
|
||||
|
||||
//// [unparenthesizedFunctionTypeInUnionOrIntersection.js]
|
||||
@ -0,0 +1,76 @@
|
||||
=== tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts ===
|
||||
type U1 = string | () => void;
|
||||
>U1 : Symbol(U1, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 0, 0))
|
||||
|
||||
type U2 = string | (foo: number) => void
|
||||
>U2 : Symbol(U2, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 0, 30))
|
||||
>foo : Symbol(foo, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 1, 20))
|
||||
|
||||
type U3 = | () => number
|
||||
>U3 : Symbol(U3, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 1, 40))
|
||||
|
||||
type U4 = | (foo?: number) => void;
|
||||
>U4 : Symbol(U4, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 2, 24))
|
||||
>foo : Symbol(foo, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 3, 13))
|
||||
|
||||
type U5 = string | (number: number, foo?: string) => void | number;
|
||||
>U5 : Symbol(U5, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 3, 35))
|
||||
>number : Symbol(number, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 4, 20))
|
||||
>foo : Symbol(foo, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 4, 35))
|
||||
|
||||
type U6 =
|
||||
>U6 : Symbol(U6, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 4, 67))
|
||||
|
||||
| string
|
||||
| (...args: any[]) => void
|
||||
>args : Symbol(args, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 7, 5))
|
||||
|
||||
| number;
|
||||
|
||||
type I1 = string & () => void;
|
||||
>I1 : Symbol(I1, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 8, 11))
|
||||
|
||||
type I2 = string & (...foo: number[]) => void;
|
||||
>I2 : Symbol(I2, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 10, 30))
|
||||
>foo : Symbol(foo, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 11, 20))
|
||||
|
||||
type I3 = & () => boolean
|
||||
>I3 : Symbol(I3, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 11, 46))
|
||||
|
||||
type I4 = & () => boolean & null;
|
||||
>I4 : Symbol(I4, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 12, 25))
|
||||
|
||||
type I5 = string & (any: any, any2: any) => any & any;
|
||||
>I5 : Symbol(I5, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 13, 33))
|
||||
>any : Symbol(any, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 14, 20))
|
||||
>any2 : Symbol(any2, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 14, 29))
|
||||
|
||||
type I6 =
|
||||
>I6 : Symbol(I6, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 14, 54))
|
||||
|
||||
& string
|
||||
& (foo: any) => void;
|
||||
>foo : Symbol(foo, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 17, 5))
|
||||
|
||||
type M1 = string | number & string | () => number;
|
||||
>M1 : Symbol(M1, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 17, 23))
|
||||
|
||||
type M2 = any & string | any & () => void;
|
||||
>M2 : Symbol(M2, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 19, 50))
|
||||
|
||||
type M3 = any & (foo: any) => void | () => void & any;
|
||||
>M3 : Symbol(M3, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 20, 42))
|
||||
>foo : Symbol(foo, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 21, 17))
|
||||
|
||||
type OK1 = string | (number);
|
||||
>OK1 : Symbol(OK1, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 21, 54))
|
||||
|
||||
type OK2 = string | ((number));
|
||||
>OK2 : Symbol(OK2, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 23, 29))
|
||||
|
||||
type OK3 = string | (()=> void);
|
||||
>OK3 : Symbol(OK3, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 24, 31))
|
||||
|
||||
type OK4 = string | (()=> string | number);
|
||||
>OK4 : Symbol(OK4, Decl(unparenthesizedFunctionTypeInUnionOrIntersection.ts, 25, 32))
|
||||
|
||||
@ -0,0 +1,77 @@
|
||||
=== tests/cases/compiler/unparenthesizedFunctionTypeInUnionOrIntersection.ts ===
|
||||
type U1 = string | () => void;
|
||||
>U1 : U1
|
||||
|
||||
type U2 = string | (foo: number) => void
|
||||
>U2 : U2
|
||||
>foo : number
|
||||
|
||||
type U3 = | () => number
|
||||
>U3 : () => number
|
||||
|
||||
type U4 = | (foo?: number) => void;
|
||||
>U4 : (foo?: number) => void
|
||||
>foo : number
|
||||
|
||||
type U5 = string | (number: number, foo?: string) => void | number;
|
||||
>U5 : U5
|
||||
>number : number
|
||||
>foo : string
|
||||
|
||||
type U6 =
|
||||
>U6 : U6
|
||||
|
||||
| string
|
||||
| (...args: any[]) => void
|
||||
>args : any[]
|
||||
|
||||
| number;
|
||||
|
||||
type I1 = string & () => void;
|
||||
>I1 : I1
|
||||
|
||||
type I2 = string & (...foo: number[]) => void;
|
||||
>I2 : I2
|
||||
>foo : number[]
|
||||
|
||||
type I3 = & () => boolean
|
||||
>I3 : () => boolean
|
||||
|
||||
type I4 = & () => boolean & null;
|
||||
>I4 : () => boolean & null
|
||||
>null : null
|
||||
|
||||
type I5 = string & (any: any, any2: any) => any & any;
|
||||
>I5 : I5
|
||||
>any : any
|
||||
>any2 : any
|
||||
|
||||
type I6 =
|
||||
>I6 : I6
|
||||
|
||||
& string
|
||||
& (foo: any) => void;
|
||||
>foo : any
|
||||
|
||||
type M1 = string | number & string | () => number;
|
||||
>M1 : M1
|
||||
|
||||
type M2 = any & string | any & () => void;
|
||||
>M2 : any
|
||||
|
||||
type M3 = any & (foo: any) => void | () => void & any;
|
||||
>M3 : any
|
||||
>foo : any
|
||||
|
||||
type OK1 = string | (number);
|
||||
>OK1 : OK1
|
||||
|
||||
type OK2 = string | ((number));
|
||||
>OK2 : OK1
|
||||
|
||||
type OK3 = string | (()=> void);
|
||||
>OK3 : OK3
|
||||
|
||||
type OK4 = string | (()=> string | number);
|
||||
>OK4 : OK4
|
||||
|
||||
@ -0,0 +1,25 @@
|
||||
type U1 = string | new () => void;
|
||||
type U2 = string | new (foo: number) => void
|
||||
type U3 = | new () => number
|
||||
type U4 = | new (foo?: number) => void;
|
||||
type U5 = string | new (number: number, foo?: string) => void | number;
|
||||
type U6 =
|
||||
| string
|
||||
| new (...args: any[]) => void
|
||||
| number;
|
||||
|
||||
type I1 = string & new () => void;
|
||||
type I2 = string & new (...foo: number[]) => void;
|
||||
type I3 = & new () => boolean
|
||||
type I4 = & new () => boolean & null;
|
||||
type I5 = string & new (any: any, any2: any) => any & any;
|
||||
type I6 =
|
||||
& string
|
||||
& new (foo: any) => void;
|
||||
|
||||
type M1 = string | number & string | new () => number;
|
||||
type M2 = any & string | any & new () => void;
|
||||
type M3 = any & new (foo: any) => void | new () => void & any;
|
||||
|
||||
type OK1 = string | (new ()=> void);
|
||||
type OK2 = string | (new ()=> string | number);
|
||||
@ -0,0 +1,27 @@
|
||||
type U1 = string | () => void;
|
||||
type U2 = string | (foo: number) => void
|
||||
type U3 = | () => number
|
||||
type U4 = | (foo?: number) => void;
|
||||
type U5 = string | (number: number, foo?: string) => void | number;
|
||||
type U6 =
|
||||
| string
|
||||
| (...args: any[]) => void
|
||||
| number;
|
||||
|
||||
type I1 = string & () => void;
|
||||
type I2 = string & (...foo: number[]) => void;
|
||||
type I3 = & () => boolean
|
||||
type I4 = & () => boolean & null;
|
||||
type I5 = string & (any: any, any2: any) => any & any;
|
||||
type I6 =
|
||||
& string
|
||||
& (foo: any) => void;
|
||||
|
||||
type M1 = string | number & string | () => number;
|
||||
type M2 = any & string | any & () => void;
|
||||
type M3 = any & (foo: any) => void | () => void & any;
|
||||
|
||||
type OK1 = string | (number);
|
||||
type OK2 = string | ((number));
|
||||
type OK3 = string | (()=> void);
|
||||
type OK4 = string | (()=> string | number);
|
||||
Loading…
x
Reference in New Issue
Block a user