Skip to content

Commit e836fe1

Browse files
committed
Initial implementation of Union Types
1 parent 438aa89 commit e836fe1

6 files changed

+407
-209
lines changed

src/compiler/checker.ts

+360-183
Large diffs are not rendered by default.

src/compiler/core.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ module ts {
8282
return array1.concat(array2);
8383
}
8484

85-
export function uniqueElements<T>(array: T[]): T[] {
85+
export function deduplicate<T>(array: T[]): T[] {
8686
if (array) {
8787
var result: T[] = [];
8888
for (var i = 0, len = array.length; i < len; i++) {

src/compiler/diagnosticInformationMap.generated.ts

-2
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,6 @@ module ts {
179179
The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type: { code: 2363, category: DiagnosticCategory.Error, key: "The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type." },
180180
Invalid_left_hand_side_of_assignment_expression: { code: 2364, category: DiagnosticCategory.Error, key: "Invalid left-hand side of assignment expression." },
181181
Operator_0_cannot_be_applied_to_types_1_and_2: { code: 2365, category: DiagnosticCategory.Error, key: "Operator '{0}' cannot be applied to types '{1}' and '{2}'." },
182-
No_best_common_type_exists_between_0_1_and_2: { code: 2366, category: DiagnosticCategory.Error, key: "No best common type exists between '{0}', '{1}', and '{2}'." },
183-
No_best_common_type_exists_between_0_and_1: { code: 2367, category: DiagnosticCategory.Error, key: "No best common type exists between '{0}' and '{1}'." },
184182
Type_parameter_name_cannot_be_0: { code: 2368, category: DiagnosticCategory.Error, key: "Type parameter name cannot be '{0}'" },
185183
A_parameter_property_is_only_allowed_in_a_constructor_implementation: { code: 2369, category: DiagnosticCategory.Error, key: "A parameter property is only allowed in a constructor implementation." },
186184
A_rest_parameter_must_be_of_an_array_type: { code: 2370, category: DiagnosticCategory.Error, key: "A rest parameter must be of an array type." },

src/compiler/diagnosticMessages.json

-8
Original file line numberDiff line numberDiff line change
@@ -708,14 +708,6 @@
708708
"category": "Error",
709709
"code": 2365
710710
},
711-
"No best common type exists between '{0}', '{1}', and '{2}'.": {
712-
"category": "Error",
713-
"code": 2366
714-
},
715-
"No best common type exists between '{0}' and '{1}'.": {
716-
"category": "Error",
717-
"code": 2367
718-
},
719711
"Type parameter name cannot be '{0}'": {
720712
"category": "Error",
721713
"code": 2368

src/compiler/parser.ts

+20-2
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,8 @@ module ts {
232232
return child((<ArrayTypeNode>node).elementType);
233233
case SyntaxKind.TupleType:
234234
return children((<TupleTypeNode>node).elementTypes);
235+
case SyntaxKind.UnionType:
236+
return children((<UnionTypeNode>node).types);
235237
case SyntaxKind.ArrayLiteral:
236238
return children((<ArrayLiteral>node).elements);
237239
case SyntaxKind.ObjectLiteral:
@@ -1728,9 +1730,9 @@ module ts {
17281730
}
17291731
}
17301732

1731-
function parseType(): TypeNode {
1733+
function parseNonUnionType(): TypeNode {
17321734
var type = parseNonArrayType();
1733-
while (type && !scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.OpenBracketToken)) {
1735+
while (!scanner.hasPrecedingLineBreak() && parseOptional(SyntaxKind.OpenBracketToken)) {
17341736
parseExpected(SyntaxKind.CloseBracketToken);
17351737
var node = <ArrayTypeNode>createNode(SyntaxKind.ArrayType, type.pos);
17361738
node.elementType = type;
@@ -1739,6 +1741,22 @@ module ts {
17391741
return type;
17401742
}
17411743

1744+
function parseType(): TypeNode {
1745+
var type = parseNonUnionType();
1746+
if (token === SyntaxKind.BarToken) {
1747+
var types = <NodeArray<TypeNode>>[type];
1748+
types.pos = type.pos;
1749+
while (parseOptional(SyntaxKind.BarToken)) {
1750+
types.push(parseNonUnionType());
1751+
}
1752+
types.end = getNodeEnd();
1753+
var node = <UnionTypeNode>createNode(SyntaxKind.UnionType, type.pos);
1754+
node.types = types;
1755+
type = finishNode(node);
1756+
}
1757+
return type;
1758+
}
1759+
17421760
function parseTypeAnnotation(): TypeNode {
17431761
return parseOptional(SyntaxKind.ColonToken) ? parseType() : undefined;
17441762
}

src/compiler/types.ts

+26-13
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ module ts {
154154
TypeLiteral,
155155
ArrayType,
156156
TupleType,
157+
UnionType,
157158
// Expression
158159
ArrayLiteral,
159160
ObjectLiteral,
@@ -224,7 +225,7 @@ module ts {
224225
FirstFutureReservedWord = ImplementsKeyword,
225226
LastFutureReservedWord = YieldKeyword,
226227
FirstTypeNode = TypeReference,
227-
LastTypeNode = TupleType,
228+
LastTypeNode = UnionType,
228229
FirstPunctuation = OpenBraceToken,
229230
LastPunctuation = CaretEqualsToken,
230231
FirstToken = EndOfFileToken,
@@ -337,6 +338,10 @@ module ts {
337338
elementTypes: NodeArray<TypeNode>;
338339
}
339340

341+
export interface UnionTypeNode extends TypeNode {
342+
types: NodeArray<TypeNode>;
343+
}
344+
340345
export interface StringLiteralTypeNode extends TypeNode {
341346
text: string;
342347
}
@@ -728,19 +733,20 @@ module ts {
728733
ConstructSignature = 0x00010000, // Construct signature
729734
IndexSignature = 0x00020000, // Index signature
730735
TypeParameter = 0x00040000, // Type parameter
736+
UnionProperty = 0x00080000, // Property in union type
731737

732738
// Export markers (see comment in declareModuleMember in binder)
733-
ExportValue = 0x00080000, // Exported value marker
734-
ExportType = 0x00100000, // Exported type marker
735-
ExportNamespace = 0x00200000, // Exported namespace marker
739+
ExportValue = 0x00100000, // Exported value marker
740+
ExportType = 0x00200000, // Exported type marker
741+
ExportNamespace = 0x00400000, // Exported namespace marker
736742

737-
Import = 0x00400000, // Import
738-
Instantiated = 0x00800000, // Instantiated symbol
739-
Merged = 0x01000000, // Merged symbol (created during program binding)
740-
Transient = 0x02000000, // Transient symbol (created during type check)
741-
Prototype = 0x04000000, // Symbol for the prototype property (without source code representation)
743+
Import = 0x00800000, // Import
744+
Instantiated = 0x01000000, // Instantiated symbol
745+
Merged = 0x02000000, // Merged symbol (created during program binding)
746+
Transient = 0x04000000, // Transient symbol (created during type check)
747+
Prototype = 0x08000000, // Prototype property (no source representation)
742748

743-
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor,
749+
Value = Variable | Property | EnumMember | Function | Class | Enum | ValueModule | Method | GetAccessor | SetAccessor | UnionProperty,
744750
Type = Class | Interface | Enum | TypeLiteral | ObjectLiteral | TypeParameter,
745751
Namespace = ValueModule | NamespaceModule,
746752
Module = ValueModule | NamespaceModule,
@@ -798,6 +804,7 @@ module ts {
798804
mapper?: TypeMapper; // Type mapper for instantiation alias
799805
referenced?: boolean; // True if alias symbol has been referenced as a value
800806
exportAssignSymbol?: Symbol; // Symbol exported from external module
807+
unionType?: UnionType; // Containing union type for union property
801808
}
802809

803810
export interface TransientSymbol extends Symbol, SymbolLinks { }
@@ -845,13 +852,14 @@ module ts {
845852
Interface = 0x00000800, // Interface
846853
Reference = 0x00001000, // Generic type reference
847854
Tuple = 0x00002000, // Tuple
848-
Anonymous = 0x00004000, // Anonymous
849-
FromSignature = 0x00008000, // Created for signature assignment check
855+
Union = 0x00004000, // Union
856+
Anonymous = 0x00008000, // Anonymous
857+
FromSignature = 0x00010000, // Created for signature assignment check
850858

851859
Intrinsic = Any | String | Number | Boolean | Void | Undefined | Null,
852860
StringLike = String | StringLiteral,
853861
NumberLike = Number | Enum,
854-
ObjectType = Class | Interface | Reference | Tuple | Anonymous
862+
ObjectType = Class | Interface | Reference | Tuple | Union | Anonymous
855863
}
856864

857865
// Properties common to all types
@@ -909,6 +917,10 @@ module ts {
909917
baseArrayType: TypeReference; // Array<T> where T is best common type of element types
910918
}
911919

920+
export interface UnionType extends ObjectType {
921+
types: Type[]; // Constituent types
922+
}
923+
912924
// Resolved object type
913925
export interface ResolvedObjectType extends ObjectType {
914926
members: SymbolTable; // Properties by name
@@ -941,6 +953,7 @@ module ts {
941953
hasStringLiterals: boolean; // True if specialized
942954
target?: Signature; // Instantiation target
943955
mapper?: TypeMapper; // Instantiation mapper
956+
unionSignatures?: Signature[]; // Underlying signatures of a union signature
944957
erasedSignatureCache?: Signature; // Erased version of signature (deferred)
945958
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
946959
}

0 commit comments

Comments
 (0)