@@ -3592,14 +3592,15 @@ namespace ts {
3592
3592
3593
3593
function typeReferenceToTypeNode(type: TypeReference) {
3594
3594
const typeArguments: ReadonlyArray<Type> = type.typeArguments || emptyArray;
3595
- if (type.target === globalArrayType) {
3595
+ if (type.target === globalArrayType || type.target === globalReadonlyArrayType ) {
3596
3596
if (context.flags & NodeBuilderFlags.WriteArrayAsGenericType) {
3597
3597
const typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context);
3598
- return createTypeReferenceNode("Array", [typeArgumentNode]);
3598
+ return createTypeReferenceNode(type.target === globalArrayType ? "Array" : "ReadonlyArray ", [typeArgumentNode]);
3599
3599
}
3600
3600
3601
3601
const elementType = typeToTypeNodeHelper(typeArguments[0], context);
3602
- return createArrayTypeNode(elementType);
3602
+ const arrayType = createArrayTypeNode(elementType);
3603
+ return type.target === globalArrayType ? arrayType : createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, arrayType);
3603
3604
}
3604
3605
else if (type.target.objectFlags & ObjectFlags.Tuple) {
3605
3606
if (typeArguments.length > 0) {
@@ -3613,11 +3614,12 @@ namespace ts {
3613
3614
createOptionalTypeNode(tupleConstituentNodes[i]);
3614
3615
}
3615
3616
const tupleTypeNode = createTupleTypeNode(tupleConstituentNodes);
3616
- return (<TupleType>type.target).readonly ? createTypeReferenceNode("Readonly", [ tupleTypeNode] ) : tupleTypeNode;
3617
+ return (<TupleType>type.target).readonly ? createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode;
3617
3618
}
3618
3619
}
3619
3620
if (context.encounteredError || (context.flags & NodeBuilderFlags.AllowEmptyTuple)) {
3620
- return createTupleTypeNode([]);
3621
+ const tupleTypeNode = createTupleTypeNode([]);
3622
+ return (<TupleType>type.target).readonly ? createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode;
3621
3623
}
3622
3624
context.encounteredError = true;
3623
3625
return undefined!; // TODO: GH#18217
@@ -9030,11 +9032,15 @@ namespace ts {
9030
9032
function getTypeFromArrayTypeNode(node: ArrayTypeNode): Type {
9031
9033
const links = getNodeLinks(node);
9032
9034
if (!links.resolvedType) {
9033
- links.resolvedType = createArrayType(getTypeFromTypeNode(node.elementType));
9035
+ links.resolvedType = createArrayType(getTypeFromTypeNode(node.elementType), isReadonlyTypeOperator(node.parent) );
9034
9036
}
9035
9037
return links.resolvedType;
9036
9038
}
9037
9039
9040
+ function isReadonlyTypeOperator(node: Node) {
9041
+ return isTypeOperatorNode(node) && node.operator === SyntaxKind.ReadonlyKeyword;
9042
+ }
9043
+
9038
9044
// We represent tuple types as type references to synthesized generic interface types created by
9039
9045
// this function. The types are of the form:
9040
9046
//
@@ -9114,7 +9120,7 @@ namespace ts {
9114
9120
const type = getTypeFromTypeNode(n);
9115
9121
return n === restElement && getIndexTypeOfType(type, IndexKind.Number) || type;
9116
9122
});
9117
- links.resolvedType = createTupleType(elementTypes, minLength, !!restElement);
9123
+ links.resolvedType = createTupleType(elementTypes, minLength, !!restElement, isReadonlyTypeOperator(node.parent) );
9118
9124
}
9119
9125
return links.resolvedType;
9120
9126
}
@@ -9667,6 +9673,9 @@ namespace ts {
9667
9673
? getESSymbolLikeTypeForNode(walkUpParenthesizedTypes(node.parent))
9668
9674
: errorType;
9669
9675
break;
9676
+ case SyntaxKind.ReadonlyKeyword:
9677
+ links.resolvedType = getTypeFromTypeNode(node.type);
9678
+ break;
9670
9679
}
9671
9680
}
9672
9681
return links.resolvedType!; // TODO: GH#18217
@@ -30513,6 +30522,11 @@ namespace ts {
30513
30522
return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_here);
30514
30523
}
30515
30524
}
30525
+ else if (node.operator === SyntaxKind.ReadonlyKeyword) {
30526
+ if (node.type.kind !== SyntaxKind.ArrayType && node.type.kind !== SyntaxKind.TupleType) {
30527
+ return grammarErrorOnFirstToken(node, Diagnostics.readonly_type_modifier_is_only_permitted_on_array_and_typle_types, tokenToString(SyntaxKind.SymbolKeyword));
30528
+ }
30529
+ }
30516
30530
}
30517
30531
30518
30532
function checkGrammarForInvalidDynamicName(node: DeclarationName, message: DiagnosticMessage) {
0 commit comments