Merge pull request #29435 from Microsoft/readonlyArrayTuple

Improved support for read-only arrays and tuples
This commit is contained in:
Anders Hejlsberg 2019-01-29 12:25:42 -08:00 committed by GitHub
commit cf7cd624ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
45 changed files with 65420 additions and 324 deletions

View file

@ -67,6 +67,7 @@ namespace ts {
let enumCount = 0;
let instantiationDepth = 0;
let constraintDepth = 0;
let currentNode: Node | undefined;
const emptySymbols = createSymbolTable();
const identityMapper: (type: Type) => Type = identity;
@ -3592,14 +3593,15 @@ namespace ts {
function typeReferenceToTypeNode(type: TypeReference) {
const typeArguments: ReadonlyArray<Type> = type.typeArguments || emptyArray;
if (type.target === globalArrayType) {
if (type.target === globalArrayType || type.target === globalReadonlyArrayType) {
if (context.flags & NodeBuilderFlags.WriteArrayAsGenericType) {
const typeArgumentNode = typeToTypeNodeHelper(typeArguments[0], context);
return createTypeReferenceNode("Array", [typeArgumentNode]);
return createTypeReferenceNode(type.target === globalArrayType ? "Array" : "ReadonlyArray", [typeArgumentNode]);
}
const elementType = typeToTypeNodeHelper(typeArguments[0], context);
return createArrayTypeNode(elementType);
const arrayType = createArrayTypeNode(elementType);
return type.target === globalArrayType ? arrayType : createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, arrayType);
}
else if (type.target.objectFlags & ObjectFlags.Tuple) {
if (typeArguments.length > 0) {
@ -3612,11 +3614,13 @@ namespace ts {
createRestTypeNode(createArrayTypeNode(tupleConstituentNodes[i])) :
createOptionalTypeNode(tupleConstituentNodes[i]);
}
return createTupleTypeNode(tupleConstituentNodes);
const tupleTypeNode = createTupleTypeNode(tupleConstituentNodes);
return (<TupleType>type.target).readonly ? createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode;
}
}
if (context.encounteredError || (context.flags & NodeBuilderFlags.AllowEmptyTuple)) {
return createTupleTypeNode([]);
const tupleTypeNode = createTupleTypeNode([]);
return (<TupleType>type.target).readonly ? createTypeOperatorNode(SyntaxKind.ReadonlyKeyword, tupleTypeNode) : tupleTypeNode;
}
context.encounteredError = true;
return undefined!; // TODO: GH#18217
@ -5932,7 +5936,7 @@ namespace ts {
function getBaseTypes(type: InterfaceType): BaseType[] {
if (!type.resolvedBaseTypes) {
if (type.objectFlags & ObjectFlags.Tuple) {
type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters || emptyArray))];
type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters || emptyArray), (<TupleType>type).readonly)];
}
else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) {
if (type.symbol.flags & SymbolFlags.Class) {
@ -7522,6 +7526,7 @@ namespace ts {
// very high likelyhood we're dealing with an infinite generic type that perpetually generates
// new type identities as we descend into it. We stop the recursion here and mark this type
// and the outer types as having circular constraints.
error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
nonTerminating = true;
return t.immediateBaseConstraint = noConstraintType;
}
@ -7640,7 +7645,7 @@ namespace ts {
const typeVariable = getHomomorphicTypeVariable(type);
if (typeVariable) {
const constraint = getConstraintOfTypeParameter(typeVariable);
if (constraint && (isArrayType(constraint) || isReadonlyArrayType(constraint) || isTupleType(constraint))) {
if (constraint && (isArrayType(constraint) || isTupleType(constraint))) {
const mapper = makeUnaryTypeMapper(typeVariable, constraint);
return instantiateType(type, combineTypeMappers(mapper, type.mapper));
}
@ -9037,22 +9042,22 @@ namespace ts {
return createTypeFromGenericGlobalType(getGlobalIterableIteratorType(/*reportErrors*/ true), [iteratedType]);
}
function createArrayType(elementType: Type): ObjectType {
return createTypeFromGenericGlobalType(globalArrayType, [elementType]);
}
function createReadonlyArrayType(elementType: Type): ObjectType {
return createTypeFromGenericGlobalType(globalReadonlyArrayType, [elementType]);
function createArrayType(elementType: Type, readonly?: boolean): ObjectType {
return createTypeFromGenericGlobalType(readonly ? globalReadonlyArrayType : globalArrayType, [elementType]);
}
function getTypeFromArrayTypeNode(node: ArrayTypeNode): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
links.resolvedType = createArrayType(getTypeFromTypeNode(node.elementType));
links.resolvedType = createArrayType(getTypeFromTypeNode(node.elementType), isReadonlyTypeOperator(node.parent));
}
return links.resolvedType;
}
function isReadonlyTypeOperator(node: Node) {
return isTypeOperatorNode(node) && node.operator === SyntaxKind.ReadonlyKeyword;
}
// We represent tuple types as type references to synthesized generic interface types created by
// this function. The types are of the form:
//
@ -9060,7 +9065,7 @@ namespace ts {
//
// Note that the generic type created by this function has no symbol associated with it. The same
// is true for each of the synthesized type parameters.
function createTupleTypeOfArity(arity: number, minLength: number, hasRestElement: boolean, associatedNames: __String[] | undefined): TupleType {
function createTupleTypeOfArity(arity: number, minLength: number, hasRestElement: boolean, readonly: boolean, associatedNames: __String[] | undefined): TupleType {
let typeParameters: TypeParameter[] | undefined;
const properties: Symbol[] = [];
const maxLength = hasRestElement ? arity - 1 : arity;
@ -9069,7 +9074,8 @@ namespace ts {
for (let i = 0; i < arity; i++) {
const typeParameter = typeParameters[i] = createTypeParameter();
if (i < maxLength) {
const property = createSymbol(SymbolFlags.Property | (i >= minLength ? SymbolFlags.Optional : 0), "" + i as __String);
const property = createSymbol(SymbolFlags.Property | (i >= minLength ? SymbolFlags.Optional : 0),
"" + i as __String, readonly ? CheckFlags.Readonly : 0);
property.type = typeParameter;
properties.push(property);
}
@ -9098,25 +9104,26 @@ namespace ts {
type.declaredNumberIndexInfo = undefined;
type.minLength = minLength;
type.hasRestElement = hasRestElement;
type.readonly = readonly;
type.associatedNames = associatedNames;
return type;
}
function getTupleTypeOfArity(arity: number, minLength: number, hasRestElement: boolean, associatedNames?: __String[]): GenericType {
const key = arity + (hasRestElement ? "+" : ",") + minLength + (associatedNames && associatedNames.length ? "," + associatedNames.join(",") : "");
function getTupleTypeOfArity(arity: number, minLength: number, hasRestElement: boolean, readonly: boolean, associatedNames?: __String[]): GenericType {
const key = arity + (hasRestElement ? "+" : ",") + minLength + (readonly ? "R" : "") + (associatedNames && associatedNames.length ? "," + associatedNames.join(",") : "");
let type = tupleTypes.get(key);
if (!type) {
tupleTypes.set(key, type = createTupleTypeOfArity(arity, minLength, hasRestElement, associatedNames));
tupleTypes.set(key, type = createTupleTypeOfArity(arity, minLength, hasRestElement, readonly, associatedNames));
}
return type;
}
function createTupleType(elementTypes: ReadonlyArray<Type>, minLength = elementTypes.length, hasRestElement = false, associatedNames?: __String[]) {
function createTupleType(elementTypes: ReadonlyArray<Type>, minLength = elementTypes.length, hasRestElement = false, readonly = false, associatedNames?: __String[]) {
const arity = elementTypes.length;
if (arity === 1 && hasRestElement) {
return createArrayType(elementTypes[0]);
}
const tupleType = getTupleTypeOfArity(arity, minLength, arity > 0 && hasRestElement, associatedNames);
const tupleType = getTupleTypeOfArity(arity, minLength, arity > 0 && hasRestElement, readonly, associatedNames);
return elementTypes.length ? createTypeReference(tupleType, elementTypes) : tupleType;
}
@ -9130,7 +9137,7 @@ namespace ts {
const type = getTypeFromTypeNode(n);
return n === restElement && getIndexTypeOfType(type, IndexKind.Number) || type;
});
links.resolvedType = createTupleType(elementTypes, minLength, !!restElement);
links.resolvedType = createTupleType(elementTypes, minLength, !!restElement, isReadonlyTypeOperator(node.parent));
}
return links.resolvedType;
}
@ -9145,6 +9152,7 @@ namespace ts {
(type.typeArguments || emptyArray).slice(index),
Math.max(0, tuple.minLength - index),
tuple.hasRestElement,
tuple.readonly,
tuple.associatedNames && tuple.associatedNames.slice(index),
);
}
@ -9234,18 +9242,6 @@ namespace ts {
return includes;
}
function isSubtypeOfAny(source: Type, targets: ReadonlyArray<Type>): boolean {
for (const target of targets) {
if (source !== target && isTypeSubtypeOf(source, target) && (
!(getObjectFlags(getTargetType(source)) & ObjectFlags.Class) ||
!(getObjectFlags(getTargetType(target)) & ObjectFlags.Class) ||
isTypeDerivedFrom(source, target))) {
return true;
}
}
return false;
}
function isSetOfLiteralsFromSameEnum(types: ReadonlyArray<Type>): boolean {
const first = types[0];
if (first.flags & TypeFlags.EnumLiteral) {
@ -9262,17 +9258,42 @@ namespace ts {
return false;
}
function removeSubtypes(types: Type[]) {
if (types.length === 0 || isSetOfLiteralsFromSameEnum(types)) {
return;
function removeSubtypes(types: Type[], primitivesOnly: boolean): boolean {
const len = types.length;
if (len === 0 || isSetOfLiteralsFromSameEnum(types)) {
return true;
}
let i = types.length;
let i = len;
let count = 0;
while (i > 0) {
i--;
if (isSubtypeOfAny(types[i], types)) {
orderedRemoveItemAt(types, i);
const source = types[i];
for (const target of types) {
if (source !== target) {
if (count === 10000) {
// After 10000 subtype checks we estimate the remaining amount of work by assuming the
// same ratio of checks to removals. If the estimated number of remaining type checks is
// greater than an upper limit we deem the union type too complex to represent. The
// upper limit is 25M for unions of primitives only, and 1M otherwise. This for example
// caps union types at 5000 unique literal types and 1000 unique object types.
const estimatedCount = (count / (len - i)) * len;
if (estimatedCount > (primitivesOnly ? 25000000 : 1000000)) {
error(currentNode, Diagnostics.Expression_produces_a_union_type_that_is_too_complex_to_represent);
return false;
}
}
count++;
if (isTypeSubtypeOf(source, target) && (
!(getObjectFlags(getTargetType(source)) & ObjectFlags.Class) ||
!(getObjectFlags(getTargetType(target)) & ObjectFlags.Class) ||
isTypeDerivedFrom(source, target))) {
orderedRemoveItemAt(types, i);
break;
}
}
}
}
return true;
}
function removeRedundantLiteralTypes(types: Type[], includes: TypeFlags) {
@ -9319,7 +9340,9 @@ namespace ts {
}
break;
case UnionReduction.Subtype:
removeSubtypes(typeSet);
if (!removeSubtypes(typeSet, !(includes & TypeFlags.StructuredOrInstantiable))) {
return errorType;
}
break;
}
if (typeSet.length === 0) {
@ -9682,6 +9705,9 @@ namespace ts {
? getESSymbolLikeTypeForNode(walkUpParenthesizedTypes(node.parent))
: errorType;
break;
case SyntaxKind.ReadonlyKeyword:
links.resolvedType = getTypeFromTypeNode(node.type);
break;
}
}
return links.resolvedType!; // TODO: GH#18217
@ -10714,7 +10740,7 @@ namespace ts {
}
// Keep the flags from the symbol we're instantiating. Mark that is instantiated, and
// also transient so that we can just store data on it directly.
const result = createSymbol(symbol.flags, symbol.escapedName, CheckFlags.Instantiated | getCheckFlags(symbol) & (CheckFlags.Late | CheckFlags.OptionalParameter | CheckFlags.RestParameter));
const result = createSymbol(symbol.flags, symbol.escapedName, CheckFlags.Instantiated | getCheckFlags(symbol) & (CheckFlags.Readonly | CheckFlags.Late | CheckFlags.OptionalParameter | CheckFlags.RestParameter));
result.declarations = symbol.declarations;
result.parent = symbol.parent;
result.target = symbol;
@ -10845,11 +10871,11 @@ namespace ts {
return errorType;
}
type.instantiating = true;
const modifiers = getMappedTypeModifiers(type);
const result = mapType(mappedTypeVariable, t => {
if (t.flags & (TypeFlags.AnyOrUnknown | TypeFlags.InstantiableNonPrimitive | TypeFlags.Object | TypeFlags.Intersection) && t !== wildcardType) {
const replacementMapper = createReplacementMapper(typeVariable, t, mapper);
return isArrayType(t) ? createArrayType(instantiateMappedTypeTemplate(type, numberType, /*isOptional*/ true, replacementMapper)) :
isReadonlyArrayType(t) ? createReadonlyArrayType(instantiateMappedTypeTemplate(type, numberType, /*isOptional*/ true, replacementMapper)) :
return isArrayType(t) ? createArrayType(instantiateMappedTypeTemplate(type, numberType, /*isOptional*/ true, replacementMapper), getModifiedReadonlyState(isReadonlyArrayType(t), modifiers)) :
isTupleType(t) ? instantiateMappedTupleType(t, type, replacementMapper) :
instantiateAnonymousType(type, replacementMapper);
}
@ -10862,6 +10888,10 @@ namespace ts {
return instantiateAnonymousType(type, mapper);
}
function getModifiedReadonlyState(state: boolean, modifiers: MappedTypeModifiers) {
return modifiers & MappedTypeModifiers.IncludeReadonly ? true : modifiers & MappedTypeModifiers.ExcludeReadonly ? false : state;
}
function instantiateMappedTupleType(tupleType: TupleTypeReference, mappedType: MappedType, mapper: TypeMapper) {
const minLength = tupleType.target.minLength;
const elementTypes = map(tupleType.typeArguments || emptyArray, (_, i) =>
@ -10870,7 +10900,8 @@ namespace ts {
const newMinLength = modifiers & MappedTypeModifiers.IncludeOptional ? 0 :
modifiers & MappedTypeModifiers.ExcludeOptional ? getTypeReferenceArity(tupleType) - (tupleType.target.hasRestElement ? 1 : 0) :
minLength;
return createTupleType(elementTypes, newMinLength, tupleType.target.hasRestElement, tupleType.target.associatedNames);
const newReadonly = getModifiedReadonlyState(tupleType.target.readonly, modifiers);
return createTupleType(elementTypes, newMinLength, tupleType.target.hasRestElement, newReadonly, tupleType.target.associatedNames);
}
function instantiateMappedTypeTemplate(type: MappedType, key: Type, isOptional: boolean, mapper: TypeMapper) {
@ -10943,6 +10974,7 @@ namespace ts {
// We have reached 50 recursive type instantiations and there is a very high likelyhood we're dealing
// with a combination of infinite generic types that perpetually generate new type identities. We stop
// the recursion here by yielding the error type.
error(currentNode, Diagnostics.Type_instantiation_is_excessively_deep_and_possibly_infinite);
return errorType;
}
instantiationDepth++;
@ -12732,7 +12764,7 @@ namespace ts {
errorInfo = saveErrorInfo;
}
}
else if (isTupleType(source) && (isArrayType(target) || isReadonlyArrayType(target)) || isArrayType(source) && isReadonlyArrayType(target)) {
else if (isReadonlyArrayType(target) ? isArrayType(source) || isTupleType(source) : isArrayType(target) && isTupleType(source) && !source.target.readonly) {
return isRelatedTo(getIndexTypeOfType(source, IndexKind.Number) || anyType, getIndexTypeOfType(target, IndexKind.Number) || anyType, reportErrors);
}
// Even if relationship doesn't hold for unions, intersections, or generic type references,
@ -13273,11 +13305,8 @@ namespace ts {
}
function getVariances(type: GenericType): Variance[] {
if (!strictFunctionTypes) {
return emptyArray;
}
if (type === globalArrayType || type === globalReadonlyArrayType) {
// Arrays are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters)
// Arrays and tuples are known to be covariant, no need to spend time computing this (emptyArray implies covariance for all parameters)
if (!strictFunctionTypes || type === globalArrayType || type === globalReadonlyArrayType || type.objectFlags & ObjectFlags.Tuple) {
return emptyArray;
}
return getVariancesWorker(type.typeParameters, type, getMarkerTypeReference);
@ -13567,7 +13596,7 @@ namespace ts {
}
function isArrayType(type: Type): boolean {
return !!(getObjectFlags(type) & ObjectFlags.Reference) && (<TypeReference>type).target === globalArrayType;
return !!(getObjectFlags(type) & ObjectFlags.Reference) && ((<TypeReference>type).target === globalArrayType || (<TypeReference>type).target === globalReadonlyArrayType);
}
function isReadonlyArrayType(type: Type): boolean {
@ -13581,8 +13610,7 @@ namespace ts {
function isArrayLikeType(type: Type): boolean {
// A type is array-like if it is a reference to the global Array or global ReadonlyArray type,
// or if it is not the undefined or null type and if it is assignable to ReadonlyArray<any>
return getObjectFlags(type) & ObjectFlags.Reference && ((<TypeReference>type).target === globalArrayType || (<TypeReference>type).target === globalReadonlyArrayType) ||
!(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
return isArrayType(type) || !(type.flags & TypeFlags.Nullable) && isTypeAssignableTo(type, anyReadonlyArrayType);
}
function isEmptyArrayLiteralType(type: Type): boolean {
@ -14191,16 +14219,13 @@ namespace ts {
// For arrays and tuples we infer new arrays and tuples where the reverse mapping has been
// applied to the element type(s).
if (isArrayType(source)) {
return createArrayType(inferReverseMappedType((<TypeReference>source).typeArguments![0], target, constraint));
}
if (isReadonlyArrayType(source)) {
return createReadonlyArrayType(inferReverseMappedType((<TypeReference>source).typeArguments![0], target, constraint));
return createArrayType(inferReverseMappedType((<TypeReference>source).typeArguments![0], target, constraint), isReadonlyArrayType(source));
}
if (isTupleType(source)) {
const elementTypes = map(source.typeArguments || emptyArray, t => inferReverseMappedType(t, target, constraint));
const minLength = getMappedTypeModifiers(target) & MappedTypeModifiers.IncludeOptional ?
getTypeReferenceArity(source) - (source.target.hasRestElement ? 1 : 0) : source.target.minLength;
return createTupleType(elementTypes, minLength, source.target.hasRestElement, source.target.associatedNames);
return createTupleType(elementTypes, minLength, source.target.hasRestElement, source.target.readonly, source.target.associatedNames);
}
// For all other object types we infer a new object type where the reverse mapping has been
// applied to the type of each property.
@ -18107,7 +18132,9 @@ namespace ts {
return createTupleType(elementTypes, minLength, hasRestElement);
}
}
return getArrayLiteralType(elementTypes, UnionReduction.Subtype);
return createArrayType(elementTypes.length ?
getUnionType(elementTypes, UnionReduction.Subtype) :
strictNullChecks ? implicitNeverType : undefinedWideningType);
}
function getArrayLiteralTupleTypeIfApplicable(elementTypes: Type[], contextualType: Type | undefined, hasRestElement: boolean, elementCount = elementTypes.length) {
@ -18136,12 +18163,6 @@ namespace ts {
}
}
function getArrayLiteralType(elementTypes: Type[], unionReduction = UnionReduction.Literal) {
return createArrayType(elementTypes.length ?
getUnionType(elementTypes, unionReduction) :
strictNullChecks ? implicitNeverType : undefinedWideningType);
}
function isNumericName(name: DeclarationName): boolean {
switch (name.kind) {
case SyntaxKind.ComputedPropertyName:
@ -21423,7 +21444,7 @@ namespace ts {
}
const minArgumentCount = getMinArgumentCount(source);
const minLength = minArgumentCount < start ? 0 : minArgumentCount - start;
return createTupleType(types, minLength, !!restType, names);
return createTupleType(types, minLength, !!restType, /*readonly*/ false, names);
}
function getParameterCount(signature: Signature) {
@ -23060,7 +23081,7 @@ namespace ts {
return instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
}
function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration, type: Type, checkMode?: CheckMode) {
function instantiateTypeWithSingleGenericCallSignature(node: Expression | MethodDeclaration | QualifiedName, type: Type, checkMode?: CheckMode) {
if (checkMode === CheckMode.Inferential) {
const signature = getSingleCallSignature(type);
if (signature && signature.typeParameters) {
@ -23130,15 +23151,10 @@ namespace ts {
// have the wildcard function type; this form of type check is used during overload resolution to exclude
// contextually typed function and arrow expressions in the initial phase.
function checkExpression(node: Expression | QualifiedName, checkMode?: CheckMode, forceTuple?: boolean): Type {
let type: Type;
if (node.kind === SyntaxKind.QualifiedName) {
type = checkQualifiedName(<QualifiedName>node);
}
else {
const uninstantiatedType = checkExpressionWorker(node, checkMode, forceTuple);
type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
}
const saveCurrentNode = currentNode;
currentNode = node;
const uninstantiatedType = checkExpressionWorker(node, checkMode, forceTuple);
const type = instantiateTypeWithSingleGenericCallSignature(node, uninstantiatedType, checkMode);
if (isConstEnumObjectType(type)) {
// enum object type for const enums are only permitted in:
// - 'left' in property access
@ -23154,6 +23170,7 @@ namespace ts {
error(node, Diagnostics.const_enums_can_only_be_used_in_property_or_index_access_expressions_or_the_right_hand_side_of_an_import_declaration_or_export_assignment_or_type_query);
}
}
currentNode = saveCurrentNode;
return type;
}
@ -23165,7 +23182,7 @@ namespace ts {
return checkExpression(node.expression, checkMode);
}
function checkExpressionWorker(node: Expression, checkMode: CheckMode | undefined, forceTuple?: boolean): Type {
function checkExpressionWorker(node: Expression | QualifiedName, checkMode: CheckMode | undefined, forceTuple?: boolean): Type {
switch (node.kind) {
case SyntaxKind.Identifier:
return checkIdentifier(<Identifier>node);
@ -23198,6 +23215,8 @@ namespace ts {
return checkObjectLiteral(<ObjectLiteralExpression>node, checkMode);
case SyntaxKind.PropertyAccessExpression:
return checkPropertyAccessExpression(<PropertyAccessExpression>node);
case SyntaxKind.QualifiedName:
return checkQualifiedName(<QualifiedName>node);
case SyntaxKind.ElementAccessExpression:
return checkIndexedAccess(<ElementAccessExpression>node);
case SyntaxKind.CallExpression:
@ -23321,7 +23340,7 @@ namespace ts {
// Only check rest parameter type if it's not a binding pattern. Since binding patterns are
// not allowed in a rest parameter, we already have an error from checkGrammarParameterList.
if (node.dotDotDotToken && !isBindingPattern(node.name) && !isTypeAssignableTo(getTypeOfSymbol(node.symbol), anyArrayType)) {
if (node.dotDotDotToken && !isBindingPattern(node.name) && !isTypeAssignableTo(getTypeOfSymbol(node.symbol), anyReadonlyArrayType)) {
error(node, Diagnostics.A_rest_parameter_must_be_of_an_array_type);
}
}
@ -27879,10 +27898,15 @@ namespace ts {
}
function checkSourceElement(node: Node | undefined): void {
if (!node) {
return;
if (node) {
const saveCurrentNode = currentNode;
currentNode = node;
checkSourceElementWorker(node);
currentNode = saveCurrentNode;
}
}
function checkSourceElementWorker(node: Node): void {
if (isInJSFile(node)) {
forEach((node as JSDocContainer).jsDoc, ({ tags }) => forEach(tags, checkSourceElement));
}
@ -28140,32 +28164,36 @@ namespace ts {
function checkDeferredNodes(context: SourceFile) {
const links = getNodeLinks(context);
if (!links.deferredNodes) {
return;
if (links.deferredNodes) {
links.deferredNodes.forEach(checkDeferredNode);
}
links.deferredNodes.forEach(node => {
switch (node.kind) {
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
checkFunctionExpressionOrObjectLiteralMethodDeferred(<FunctionExpression>node);
break;
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
checkAccessorDeclaration(<AccessorDeclaration>node);
break;
case SyntaxKind.ClassExpression:
checkClassExpressionDeferred(<ClassExpression>node);
break;
case SyntaxKind.JsxSelfClosingElement:
checkJsxSelfClosingElementDeferred(<JsxSelfClosingElement>node);
break;
case SyntaxKind.JsxElement:
checkJsxElementDeferred(<JsxElement>node);
break;
}
});
}
function checkDeferredNode(node: Node) {
const saveCurrentNode = currentNode;
currentNode = node;
switch (node.kind) {
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.MethodSignature:
checkFunctionExpressionOrObjectLiteralMethodDeferred(<FunctionExpression>node);
break;
case SyntaxKind.GetAccessor:
case SyntaxKind.SetAccessor:
checkAccessorDeclaration(<AccessorDeclaration>node);
break;
case SyntaxKind.ClassExpression:
checkClassExpressionDeferred(<ClassExpression>node);
break;
case SyntaxKind.JsxSelfClosingElement:
checkJsxSelfClosingElementDeferred(<JsxSelfClosingElement>node);
break;
case SyntaxKind.JsxElement:
checkJsxElementDeferred(<JsxElement>node);
break;
}
currentNode = saveCurrentNode;
}
function checkSourceFile(node: SourceFile) {
@ -30668,6 +30696,11 @@ namespace ts {
return grammarErrorOnNode(node, Diagnostics.unique_symbol_types_are_not_allowed_here);
}
}
else if (node.operator === SyntaxKind.ReadonlyKeyword) {
if (node.type.kind !== SyntaxKind.ArrayType && node.type.kind !== SyntaxKind.TupleType) {
return grammarErrorOnFirstToken(node, Diagnostics.readonly_type_modifier_is_only_permitted_on_array_and_tuple_types, tokenToString(SyntaxKind.SymbolKeyword));
}
}
}
function checkGrammarForInvalidDynamicName(node: DeclarationName, message: DiagnosticMessage) {

View file

@ -1023,6 +1023,10 @@
"category": "Error",
"code": 1353
},
"'readonly' type modifier is only permitted on array and tuple types.": {
"category": "Error",
"code": 1354
},
"Duplicate identifier '{0}'.": {
"category": "Error",
@ -2128,6 +2132,14 @@
"category": "Error",
"code": 2588
},
"Type instantiation is excessively deep and possibly infinite.": {
"category": "Error",
"code": 2589
},
"Expression produces a union type that is too complex to represent.": {
"category": "Error",
"code": 2590
},
"JSX element attributes type '{0}' may not be a union type.": {
"category": "Error",
"code": 2600

View file

@ -876,8 +876,8 @@ namespace ts {
}
export function createTypeOperatorNode(type: TypeNode): TypeOperatorNode;
export function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode;
export function createTypeOperatorNode(operatorOrType: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | TypeNode, type?: TypeNode) {
export function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode;
export function createTypeOperatorNode(operatorOrType: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword | TypeNode, type?: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.TypeOperator) as TypeOperatorNode;
node.operator = typeof operatorOrType === "number" ? operatorOrType : SyntaxKind.KeyOfKeyword;
node.type = parenthesizeElementTypeMember(typeof operatorOrType === "number" ? type! : operatorOrType);

View file

@ -2966,6 +2966,7 @@ namespace ts {
case SyntaxKind.NumberKeyword:
case SyntaxKind.BigIntKeyword:
case SyntaxKind.BooleanKeyword:
case SyntaxKind.ReadonlyKeyword:
case SyntaxKind.SymbolKeyword:
case SyntaxKind.UniqueKeyword:
case SyntaxKind.VoidKeyword:
@ -3055,7 +3056,7 @@ namespace ts {
return finishNode(postfix);
}
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword) {
function parseTypeOperator(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword) {
const node = <TypeOperatorNode>createNode(SyntaxKind.TypeOperator);
parseExpected(operator);
node.operator = operator;
@ -3077,6 +3078,7 @@ namespace ts {
switch (operator) {
case SyntaxKind.KeyOfKeyword:
case SyntaxKind.UniqueKeyword:
case SyntaxKind.ReadonlyKeyword:
return parseTypeOperator(operator);
case SyntaxKind.InferKeyword:
return parseInferType();

View file

@ -1934,8 +1934,13 @@ namespace ts {
case SyntaxKind.ConditionalType:
return serializeTypeList([(<ConditionalTypeNode>node).trueType, (<ConditionalTypeNode>node).falseType]);
case SyntaxKind.TypeQuery:
case SyntaxKind.TypeOperator:
if ((<TypeOperatorNode>node).operator === SyntaxKind.ReadonlyKeyword) {
return serializeTypeNode((<TypeOperatorNode>node).type);
}
break;
case SyntaxKind.TypeQuery:
case SyntaxKind.IndexedAccessType:
case SyntaxKind.MappedType:
case SyntaxKind.TypeLiteral:

View file

@ -1233,7 +1233,7 @@ namespace ts {
export interface TypeOperatorNode extends TypeNode {
kind: SyntaxKind.TypeOperator;
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword;
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword;
type: TypeNode;
}
@ -4063,6 +4063,7 @@ namespace ts {
export interface TupleType extends GenericType {
minLength: number;
hasRestElement: boolean;
readonly: boolean;
associatedNames?: __String[];
}

View file

@ -814,7 +814,7 @@ declare namespace ts {
}
interface TypeOperatorNode extends TypeNode {
kind: SyntaxKind.TypeOperator;
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword;
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword;
type: TypeNode;
}
interface IndexedAccessTypeNode extends TypeNode {
@ -2286,6 +2286,7 @@ declare namespace ts {
interface TupleType extends GenericType {
minLength: number;
hasRestElement: boolean;
readonly: boolean;
associatedNames?: __String[];
}
interface TupleTypeReference extends TypeReference {
@ -3759,7 +3760,7 @@ declare namespace ts {
function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode;
function createThisTypeNode(): ThisTypeNode;
function createTypeOperatorNode(type: TypeNode): TypeOperatorNode;
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode;
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode;
function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
@ -8344,7 +8345,7 @@ declare namespace ts.server {
excludedFiles: ReadonlyArray<NormalizedPath>;
private typeAcquisition;
updateGraph(): boolean;
getExcludedFiles(): ReadonlyArray<NormalizedPath>;
getExcludedFiles(): readonly NormalizedPath[];
getTypeAcquisition(): TypeAcquisition;
setTypeAcquisition(newTypeAcquisition: TypeAcquisition): void;
}

View file

@ -814,7 +814,7 @@ declare namespace ts {
}
interface TypeOperatorNode extends TypeNode {
kind: SyntaxKind.TypeOperator;
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword;
operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword;
type: TypeNode;
}
interface IndexedAccessTypeNode extends TypeNode {
@ -2286,6 +2286,7 @@ declare namespace ts {
interface TupleType extends GenericType {
minLength: number;
hasRestElement: boolean;
readonly: boolean;
associatedNames?: __String[];
}
interface TupleTypeReference extends TypeReference {
@ -3759,7 +3760,7 @@ declare namespace ts {
function updateParenthesizedType(node: ParenthesizedTypeNode, type: TypeNode): ParenthesizedTypeNode;
function createThisTypeNode(): ThisTypeNode;
function createTypeOperatorNode(type: TypeNode): TypeOperatorNode;
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword, type: TypeNode): TypeOperatorNode;
function createTypeOperatorNode(operator: SyntaxKind.KeyOfKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.ReadonlyKeyword, type: TypeNode): TypeOperatorNode;
function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode;
function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;
function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode;

View file

@ -30,15 +30,15 @@ const foundNumber: number | undefined = arrayOfStringsNumbersAndBooleans.find(is
>isNumber : (x: any) => x is number
const readonlyArrayOfStringsNumbersAndBooleans = arrayOfStringsNumbersAndBooleans as ReadonlyArray<string | number | boolean>;
>readonlyArrayOfStringsNumbersAndBooleans : ReadonlyArray<string | number | boolean>
>arrayOfStringsNumbersAndBooleans as ReadonlyArray<string | number | boolean> : ReadonlyArray<string | number | boolean>
>readonlyArrayOfStringsNumbersAndBooleans : readonly (string | number | boolean)[]
>arrayOfStringsNumbersAndBooleans as ReadonlyArray<string | number | boolean> : readonly (string | number | boolean)[]
>arrayOfStringsNumbersAndBooleans : (string | number | boolean)[]
const readonlyFoundNumber: number | undefined = readonlyArrayOfStringsNumbersAndBooleans.find(isNumber);
>readonlyFoundNumber : number
>readonlyArrayOfStringsNumbersAndBooleans.find(isNumber) : number
>readonlyArrayOfStringsNumbersAndBooleans.find : { <S extends string | number | boolean>(predicate: (this: void, value: string | number | boolean, index: number, obj: ReadonlyArray<string | number | boolean>) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: ReadonlyArray<string | number | boolean>) => boolean, thisArg?: any): string | number | boolean; }
>readonlyArrayOfStringsNumbersAndBooleans : ReadonlyArray<string | number | boolean>
>find : { <S extends string | number | boolean>(predicate: (this: void, value: string | number | boolean, index: number, obj: ReadonlyArray<string | number | boolean>) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: ReadonlyArray<string | number | boolean>) => boolean, thisArg?: any): string | number | boolean; }
>readonlyArrayOfStringsNumbersAndBooleans.find : { <S extends string | number | boolean>(predicate: (this: void, value: string | number | boolean, index: number, obj: readonly (string | number | boolean)[]) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: readonly (string | number | boolean)[]) => boolean, thisArg?: any): string | number | boolean; }
>readonlyArrayOfStringsNumbersAndBooleans : readonly (string | number | boolean)[]
>find : { <S extends string | number | boolean>(predicate: (this: void, value: string | number | boolean, index: number, obj: readonly (string | number | boolean)[]) => value is S, thisArg?: any): S; (predicate: (value: string | number | boolean, index: number, obj: readonly (string | number | boolean)[]) => boolean, thisArg?: any): string | number | boolean; }
>isNumber : (x: any) => x is number

View file

@ -4,22 +4,22 @@ const array: number[] = [];
>[] : undefined[]
const readonlyArray: ReadonlyArray<number> = [];
>readonlyArray : ReadonlyArray<number>
>readonlyArray : readonly number[]
>[] : undefined[]
array.flatMap((): ReadonlyArray<number> => []); // ok
>array.flatMap((): ReadonlyArray<number> => []) : number[]
>array.flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
>array.flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]
>array : number[]
>flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
>(): ReadonlyArray<number> => [] : () => ReadonlyArray<number>
>flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]
>(): ReadonlyArray<number> => [] : () => readonly number[]
>[] : undefined[]
readonlyArray.flatMap((): ReadonlyArray<number> => []); // ok
>readonlyArray.flatMap((): ReadonlyArray<number> => []) : number[]
>readonlyArray.flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
>readonlyArray : ReadonlyArray<number>
>flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | ReadonlyArray<U>, thisArg?: This) => U[]
>(): ReadonlyArray<number> => [] : () => ReadonlyArray<number>
>readonlyArray.flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]
>readonlyArray : readonly number[]
>flatMap : <U, This = undefined>(callback: (this: This, value: number, index: number, array: number[]) => U | readonly U[], thisArg?: This) => U[]
>(): ReadonlyArray<number> => [] : () => readonly number[]
>[] : undefined[]

View file

@ -1,6 +1,6 @@
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray<B>'.
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(13,1): error TS2322: Type 'A[]' is not assignable to type 'readonly B[]'.
Property 'b' is missing in type 'A' but required in type 'B'.
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C<A>' is not assignable to type 'ReadonlyArray<B>'.
tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error TS2322: Type 'C<A>' is not assignable to type 'readonly B[]'.
Types of property 'concat' are incompatible.
Type '{ (...items: ConcatArray<A>[]): A[]; (...items: (A | ConcatArray<A>)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray<B>[]): B[]; (...items: (B | ConcatArray<B>)[]): B[]; }'.
Type 'A[]' is not assignable to type 'B[]'.
@ -22,7 +22,7 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T
rra = arb;
rrb = ara; // error: 'A' is not assignable to 'B'
~~~
!!! error TS2322: Type 'A[]' is not assignable to type 'ReadonlyArray<B>'.
!!! error TS2322: Type 'A[]' is not assignable to type 'readonly B[]'.
!!! error TS2322: Property 'b' is missing in type 'A' but required in type 'B'.
!!! related TS2728 tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts:2:21: 'b' is declared here.
@ -31,7 +31,7 @@ tests/cases/compiler/arrayOfSubtypeIsAssignableToReadonlyArray.ts(18,1): error T
rrb = crb;
rrb = cra; // error: 'A' is not assignable to 'B'
~~~
!!! error TS2322: Type 'C<A>' is not assignable to type 'ReadonlyArray<B>'.
!!! error TS2322: Type 'C<A>' is not assignable to type 'readonly B[]'.
!!! error TS2322: Types of property 'concat' are incompatible.
!!! error TS2322: Type '{ (...items: ConcatArray<A>[]): A[]; (...items: (A | ConcatArray<A>)[]): A[]; }' is not assignable to type '{ (...items: ConcatArray<B>[]): B[]; (...items: (B | ConcatArray<B>)[]): B[]; }'.
!!! error TS2322: Type 'A[]' is not assignable to type 'B[]'.

View file

@ -26,48 +26,48 @@ declare var crb: C<B>;
>crb : C<B>
declare var rra: ReadonlyArray<A>;
>rra : ReadonlyArray<A>
>rra : readonly A[]
declare var rrb: ReadonlyArray<B>;
>rrb : ReadonlyArray<B>
>rrb : readonly B[]
rra = ara;
>rra = ara : A[]
>rra : ReadonlyArray<A>
>rra : readonly A[]
>ara : A[]
rrb = arb; // OK, Array<B> is assignable to ReadonlyArray<A>
>rrb = arb : B[]
>rrb : ReadonlyArray<B>
>rrb : readonly B[]
>arb : B[]
rra = arb;
>rra = arb : B[]
>rra : ReadonlyArray<A>
>rra : readonly A[]
>arb : B[]
rrb = ara; // error: 'A' is not assignable to 'B'
>rrb = ara : A[]
>rrb : ReadonlyArray<B>
>rrb : readonly B[]
>ara : A[]
rra = cra;
>rra = cra : C<A>
>rra : ReadonlyArray<A>
>rra : readonly A[]
>cra : C<A>
rra = crb; // OK, C<B> is assignable to ReadonlyArray<A>
>rra = crb : C<B>
>rra : ReadonlyArray<A>
>rra : readonly A[]
>crb : C<B>
rrb = crb;
>rrb = crb : C<B>
>rrb : ReadonlyArray<B>
>rrb : readonly B[]
>crb : C<B>
rrb = cra; // error: 'A' is not assignable to 'B'
>rrb = cra : C<A>
>rrb : ReadonlyArray<B>
>rrb : readonly B[]
>cra : C<A>

View file

@ -3,9 +3,9 @@
interface Array<T> {
equalsShallow<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>): boolean;
>equalsShallow : <T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean
>this : ReadonlyArray<T>
>other : ReadonlyArray<T>
>equalsShallow : <T>(this: readonly T[], other: readonly T[]) => boolean
>this : readonly T[]
>other : readonly T[]
}
declare const a: (string | number)[] | null[] | undefined[] | {}[];
@ -19,8 +19,8 @@ declare const b: (string | number)[] | null[] | undefined[] | {}[];
let x = a.equalsShallow(b);
>x : boolean
>a.equalsShallow(b) : boolean
>a.equalsShallow : (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean)
>a.equalsShallow : (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean)
>a : (string | number)[] | null[] | undefined[] | {}[]
>equalsShallow : (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean) | (<T>(this: ReadonlyArray<T>, other: ReadonlyArray<T>) => boolean)
>equalsShallow : (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean) | (<T>(this: readonly T[], other: readonly T[]) => boolean)
>b : (string | number)[] | null[] | undefined[] | {}[]

View file

@ -3,9 +3,9 @@
Object.freeze({
>Object.freeze({ foo() { return Object.freeze('a'); },}) : Readonly<{ foo(): string; }>
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object.freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>{ foo() { return Object.freeze('a'); },} : { foo(): string; }
foo() {
@ -13,9 +13,9 @@ Object.freeze({
return Object.freeze('a');
>Object.freeze('a') : string
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object.freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>'a' : "a"
},

View file

@ -1,8 +1,8 @@
=== tests/cases/compiler/doNotInferUnrelatedTypes.ts ===
// #16709
declare function dearray<T>(ara: ReadonlyArray<T>): T;
>dearray : <T>(ara: ReadonlyArray<T>) => T
>ara : ReadonlyArray<T>
>dearray : <T>(ara: readonly T[]) => T
>ara : readonly T[]
type LiteralType = "foo" | "bar";
>LiteralType : LiteralType
@ -13,6 +13,6 @@ declare var alt: Array<LiteralType>;
let foo: LiteralType = dearray(alt);
>foo : LiteralType
>dearray(alt) : LiteralType
>dearray : <T>(ara: ReadonlyArray<T>) => T
>dearray : <T>(ara: readonly T[]) => T
>alt : LiteralType[]

View file

@ -1,13 +1,17 @@
tests/cases/compiler/infiniteConstraints.ts(3,37): error TS2589: Type instantiation is excessively deep and possibly infinite.
tests/cases/compiler/infiniteConstraints.ts(4,37): error TS2536: Type '"val"' cannot be used to index type 'B[Exclude<keyof B, K>]'.
tests/cases/compiler/infiniteConstraints.ts(31,43): error TS2322: Type 'Record<"val", "dup">' is not assignable to type 'never'.
tests/cases/compiler/infiniteConstraints.ts(31,63): error TS2322: Type 'Record<"val", "dup">' is not assignable to type 'never'.
tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' cannot be used to index type 'T[keyof T]'.
tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2589: Type instantiation is excessively deep and possibly infinite.
==== tests/cases/compiler/infiniteConstraints.ts (4 errors) ====
==== tests/cases/compiler/infiniteConstraints.ts (6 errors) ====
// Both of the following types trigger the recursion limiter in getImmediateBaseConstraint
type T1<B extends { [K in keyof B]: Extract<B[Exclude<keyof B, K>], { val: string }>["val"] }> = B;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.
type T2<B extends { [K in keyof B]: B[Exclude<keyof B, K>]["val"] }> = B;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
!!! error TS2536: Type '"val"' cannot be used to index type 'B[Exclude<keyof B, K>]'.
@ -51,4 +55,6 @@ tests/cases/compiler/infiniteConstraints.ts(36,71): error TS2536: Type '"foo"' c
declare function function1<T extends {[K in keyof T]: Cond<T[K]>}>(): T[keyof T]["foo"];
~~~~~~~~~~~~~~~~~
!!! error TS2536: Type '"foo"' cannot be used to index type 'T[keyof T]'.
~~~~~~~~~~~~~~~~~
!!! error TS2589: Type instantiation is excessively deep and possibly infinite.

View file

@ -43,7 +43,7 @@ declare function from<T>(): T[];
>from : <T>() => T[]
const c2: ReadonlyArray<A> = from();
>c2 : ReadonlyArray<Nominal<"A", string>>
>c2 : readonly Nominal<"A", string>[]
>from() : Nominal<"A", string>[]
>from : <T>() => T[]

View file

@ -1873,9 +1873,9 @@ class SampleClass<P> {
>this : this
>props : Readonly<P>
>Object.freeze(props) : Readonly<P>
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object.freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>props : P
}
}

View file

@ -28,6 +28,14 @@ type B = { b: string };
type T40 = Boxified<A | A[] | ReadonlyArray<A> | [A, B] | string | string[]>;
type ReadWrite<T> = { -readonly [P in keyof T] : T[P] };
type T50 = Readonly<string[]>;
type T51 = Readonly<[number, number]>;
type T52 = Partial<Readonly<string[]>>;
type T53 = Readonly<Partial<string[]>>;
type T54 = ReadWrite<Required<T53>>;
declare function unboxify<T>(x: Boxified<T>): T;
declare let x10: [Box<number>, Box<string>, ...Box<boolean>[]];
@ -147,6 +155,14 @@ declare type B = {
b: string;
};
declare type T40 = Boxified<A | A[] | ReadonlyArray<A> | [A, B] | string | string[]>;
declare type ReadWrite<T> = {
-readonly [P in keyof T]: T[P];
};
declare type T50 = Readonly<string[]>;
declare type T51 = Readonly<[number, number]>;
declare type T52 = Partial<Readonly<string[]>>;
declare type T53 = Readonly<Partial<string[]>>;
declare type T54 = ReadWrite<Required<T53>>;
declare function unboxify<T>(x: Boxified<T>): T;
declare let x10: [Box<number>, Box<string>, ...Box<boolean>[]];
declare let y10: [number, string, ...boolean[]];

View file

@ -108,247 +108,279 @@ type T40 = Boxified<A | A[] | ReadonlyArray<A> | [A, B] | string | string[]>;
>A : Symbol(A, Decl(mappedTypesArraysTuples.ts, 22, 39))
>B : Symbol(B, Decl(mappedTypesArraysTuples.ts, 24, 23))
type ReadWrite<T> = { -readonly [P in keyof T] : T[P] };
>ReadWrite : Symbol(ReadWrite, Decl(mappedTypesArraysTuples.ts, 27, 77))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 29, 15))
>P : Symbol(P, Decl(mappedTypesArraysTuples.ts, 29, 33))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 29, 15))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 29, 15))
>P : Symbol(P, Decl(mappedTypesArraysTuples.ts, 29, 33))
type T50 = Readonly<string[]>;
>T50 : Symbol(T50, Decl(mappedTypesArraysTuples.ts, 29, 56))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
type T51 = Readonly<[number, number]>;
>T51 : Symbol(T51, Decl(mappedTypesArraysTuples.ts, 31, 30))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
type T52 = Partial<Readonly<string[]>>;
>T52 : Symbol(T52, Decl(mappedTypesArraysTuples.ts, 32, 38))
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
type T53 = Readonly<Partial<string[]>>;
>T53 : Symbol(T53, Decl(mappedTypesArraysTuples.ts, 33, 39))
>Readonly : Symbol(Readonly, Decl(lib.es5.d.ts, --, --))
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
type T54 = ReadWrite<Required<T53>>;
>T54 : Symbol(T54, Decl(mappedTypesArraysTuples.ts, 34, 39))
>ReadWrite : Symbol(ReadWrite, Decl(mappedTypesArraysTuples.ts, 27, 77))
>Required : Symbol(Required, Decl(lib.es5.d.ts, --, --))
>T53 : Symbol(T53, Decl(mappedTypesArraysTuples.ts, 33, 39))
declare function unboxify<T>(x: Boxified<T>): T;
>unboxify : Symbol(unboxify, Decl(mappedTypesArraysTuples.ts, 27, 77))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 29, 26))
>x : Symbol(x, Decl(mappedTypesArraysTuples.ts, 29, 29))
>unboxify : Symbol(unboxify, Decl(mappedTypesArraysTuples.ts, 35, 36))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 37, 26))
>x : Symbol(x, Decl(mappedTypesArraysTuples.ts, 37, 29))
>Boxified : Symbol(Boxified, Decl(mappedTypesArraysTuples.ts, 0, 27))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 29, 26))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 29, 26))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 37, 26))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 37, 26))
declare let x10: [Box<number>, Box<string>, ...Box<boolean>[]];
>x10 : Symbol(x10, Decl(mappedTypesArraysTuples.ts, 31, 11))
>x10 : Symbol(x10, Decl(mappedTypesArraysTuples.ts, 39, 11))
>Box : Symbol(Box, Decl(mappedTypesArraysTuples.ts, 0, 0))
>Box : Symbol(Box, Decl(mappedTypesArraysTuples.ts, 0, 0))
>Box : Symbol(Box, Decl(mappedTypesArraysTuples.ts, 0, 0))
let y10 = unboxify(x10);
>y10 : Symbol(y10, Decl(mappedTypesArraysTuples.ts, 32, 3))
>unboxify : Symbol(unboxify, Decl(mappedTypesArraysTuples.ts, 27, 77))
>x10 : Symbol(x10, Decl(mappedTypesArraysTuples.ts, 31, 11))
>y10 : Symbol(y10, Decl(mappedTypesArraysTuples.ts, 40, 3))
>unboxify : Symbol(unboxify, Decl(mappedTypesArraysTuples.ts, 35, 36))
>x10 : Symbol(x10, Decl(mappedTypesArraysTuples.ts, 39, 11))
declare let x11: Box<number>[];
>x11 : Symbol(x11, Decl(mappedTypesArraysTuples.ts, 34, 11))
>x11 : Symbol(x11, Decl(mappedTypesArraysTuples.ts, 42, 11))
>Box : Symbol(Box, Decl(mappedTypesArraysTuples.ts, 0, 0))
let y11 = unboxify(x11);
>y11 : Symbol(y11, Decl(mappedTypesArraysTuples.ts, 35, 3))
>unboxify : Symbol(unboxify, Decl(mappedTypesArraysTuples.ts, 27, 77))
>x11 : Symbol(x11, Decl(mappedTypesArraysTuples.ts, 34, 11))
>y11 : Symbol(y11, Decl(mappedTypesArraysTuples.ts, 43, 3))
>unboxify : Symbol(unboxify, Decl(mappedTypesArraysTuples.ts, 35, 36))
>x11 : Symbol(x11, Decl(mappedTypesArraysTuples.ts, 42, 11))
declare let x12: { a: Box<number>, b: Box<string[]> };
>x12 : Symbol(x12, Decl(mappedTypesArraysTuples.ts, 37, 11))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 37, 18))
>x12 : Symbol(x12, Decl(mappedTypesArraysTuples.ts, 45, 11))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 45, 18))
>Box : Symbol(Box, Decl(mappedTypesArraysTuples.ts, 0, 0))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 37, 34))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 45, 34))
>Box : Symbol(Box, Decl(mappedTypesArraysTuples.ts, 0, 0))
let y12 = unboxify(x12);
>y12 : Symbol(y12, Decl(mappedTypesArraysTuples.ts, 38, 3))
>unboxify : Symbol(unboxify, Decl(mappedTypesArraysTuples.ts, 27, 77))
>x12 : Symbol(x12, Decl(mappedTypesArraysTuples.ts, 37, 11))
>y12 : Symbol(y12, Decl(mappedTypesArraysTuples.ts, 46, 3))
>unboxify : Symbol(unboxify, Decl(mappedTypesArraysTuples.ts, 35, 36))
>x12 : Symbol(x12, Decl(mappedTypesArraysTuples.ts, 45, 11))
declare function nonpartial<T>(x: Partial<T>): T;
>nonpartial : Symbol(nonpartial, Decl(mappedTypesArraysTuples.ts, 38, 24))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 40, 28))
>x : Symbol(x, Decl(mappedTypesArraysTuples.ts, 40, 31))
>nonpartial : Symbol(nonpartial, Decl(mappedTypesArraysTuples.ts, 46, 24))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 48, 28))
>x : Symbol(x, Decl(mappedTypesArraysTuples.ts, 48, 31))
>Partial : Symbol(Partial, Decl(lib.es5.d.ts, --, --))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 40, 28))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 40, 28))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 48, 28))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 48, 28))
declare let x20: [number | undefined, string?, ...boolean[]];
>x20 : Symbol(x20, Decl(mappedTypesArraysTuples.ts, 42, 11))
>x20 : Symbol(x20, Decl(mappedTypesArraysTuples.ts, 50, 11))
let y20 = nonpartial(x20);
>y20 : Symbol(y20, Decl(mappedTypesArraysTuples.ts, 43, 3))
>nonpartial : Symbol(nonpartial, Decl(mappedTypesArraysTuples.ts, 38, 24))
>x20 : Symbol(x20, Decl(mappedTypesArraysTuples.ts, 42, 11))
>y20 : Symbol(y20, Decl(mappedTypesArraysTuples.ts, 51, 3))
>nonpartial : Symbol(nonpartial, Decl(mappedTypesArraysTuples.ts, 46, 24))
>x20 : Symbol(x20, Decl(mappedTypesArraysTuples.ts, 50, 11))
declare let x21: (number | undefined)[];
>x21 : Symbol(x21, Decl(mappedTypesArraysTuples.ts, 45, 11))
>x21 : Symbol(x21, Decl(mappedTypesArraysTuples.ts, 53, 11))
let y21 = nonpartial(x21);
>y21 : Symbol(y21, Decl(mappedTypesArraysTuples.ts, 46, 3))
>nonpartial : Symbol(nonpartial, Decl(mappedTypesArraysTuples.ts, 38, 24))
>x21 : Symbol(x21, Decl(mappedTypesArraysTuples.ts, 45, 11))
>y21 : Symbol(y21, Decl(mappedTypesArraysTuples.ts, 54, 3))
>nonpartial : Symbol(nonpartial, Decl(mappedTypesArraysTuples.ts, 46, 24))
>x21 : Symbol(x21, Decl(mappedTypesArraysTuples.ts, 53, 11))
declare let x22: { a: number | undefined, b?: string[] };
>x22 : Symbol(x22, Decl(mappedTypesArraysTuples.ts, 48, 11))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 48, 18))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 48, 41))
>x22 : Symbol(x22, Decl(mappedTypesArraysTuples.ts, 56, 11))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 56, 18))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 56, 41))
let y22 = nonpartial(x22);
>y22 : Symbol(y22, Decl(mappedTypesArraysTuples.ts, 49, 3))
>nonpartial : Symbol(nonpartial, Decl(mappedTypesArraysTuples.ts, 38, 24))
>x22 : Symbol(x22, Decl(mappedTypesArraysTuples.ts, 48, 11))
>y22 : Symbol(y22, Decl(mappedTypesArraysTuples.ts, 57, 3))
>nonpartial : Symbol(nonpartial, Decl(mappedTypesArraysTuples.ts, 46, 24))
>x22 : Symbol(x22, Decl(mappedTypesArraysTuples.ts, 56, 11))
type Awaited<T> = T extends PromiseLike<infer U> ? U : T;
>Awaited : Symbol(Awaited, Decl(mappedTypesArraysTuples.ts, 49, 26))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 51, 13))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 51, 13))
>Awaited : Symbol(Awaited, Decl(mappedTypesArraysTuples.ts, 57, 26))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 59, 13))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 59, 13))
>PromiseLike : Symbol(PromiseLike, Decl(lib.es5.d.ts, --, --))
>U : Symbol(U, Decl(mappedTypesArraysTuples.ts, 51, 45))
>U : Symbol(U, Decl(mappedTypesArraysTuples.ts, 51, 45))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 51, 13))
>U : Symbol(U, Decl(mappedTypesArraysTuples.ts, 59, 45))
>U : Symbol(U, Decl(mappedTypesArraysTuples.ts, 59, 45))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 59, 13))
type Awaitified<T> = { [P in keyof T]: Awaited<T[P]> };
>Awaitified : Symbol(Awaitified, Decl(mappedTypesArraysTuples.ts, 51, 57))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 52, 16))
>P : Symbol(P, Decl(mappedTypesArraysTuples.ts, 52, 24))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 52, 16))
>Awaited : Symbol(Awaited, Decl(mappedTypesArraysTuples.ts, 49, 26))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 52, 16))
>P : Symbol(P, Decl(mappedTypesArraysTuples.ts, 52, 24))
>Awaitified : Symbol(Awaitified, Decl(mappedTypesArraysTuples.ts, 59, 57))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 60, 16))
>P : Symbol(P, Decl(mappedTypesArraysTuples.ts, 60, 24))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 60, 16))
>Awaited : Symbol(Awaited, Decl(mappedTypesArraysTuples.ts, 57, 26))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 60, 16))
>P : Symbol(P, Decl(mappedTypesArraysTuples.ts, 60, 24))
declare function all<T extends any[]>(...values: T): Promise<Awaitified<T>>;
>all : Symbol(all, Decl(mappedTypesArraysTuples.ts, 52, 55))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 54, 21))
>values : Symbol(values, Decl(mappedTypesArraysTuples.ts, 54, 38))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 54, 21))
>all : Symbol(all, Decl(mappedTypesArraysTuples.ts, 60, 55))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 62, 21))
>values : Symbol(values, Decl(mappedTypesArraysTuples.ts, 62, 38))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 62, 21))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --))
>Awaitified : Symbol(Awaitified, Decl(mappedTypesArraysTuples.ts, 51, 57))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 54, 21))
>Awaitified : Symbol(Awaitified, Decl(mappedTypesArraysTuples.ts, 59, 57))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 62, 21))
function f1(a: number, b: Promise<number>, c: string[], d: Promise<string[]>) {
>f1 : Symbol(f1, Decl(mappedTypesArraysTuples.ts, 54, 76))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 56, 12))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 56, 22))
>f1 : Symbol(f1, Decl(mappedTypesArraysTuples.ts, 62, 76))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 64, 12))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 64, 22))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --))
>c : Symbol(c, Decl(mappedTypesArraysTuples.ts, 56, 42))
>d : Symbol(d, Decl(mappedTypesArraysTuples.ts, 56, 55))
>c : Symbol(c, Decl(mappedTypesArraysTuples.ts, 64, 42))
>d : Symbol(d, Decl(mappedTypesArraysTuples.ts, 64, 55))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --))
let x1 = all(a);
>x1 : Symbol(x1, Decl(mappedTypesArraysTuples.ts, 57, 7))
>all : Symbol(all, Decl(mappedTypesArraysTuples.ts, 52, 55))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 56, 12))
>x1 : Symbol(x1, Decl(mappedTypesArraysTuples.ts, 65, 7))
>all : Symbol(all, Decl(mappedTypesArraysTuples.ts, 60, 55))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 64, 12))
let x2 = all(a, b);
>x2 : Symbol(x2, Decl(mappedTypesArraysTuples.ts, 58, 7))
>all : Symbol(all, Decl(mappedTypesArraysTuples.ts, 52, 55))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 56, 12))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 56, 22))
>x2 : Symbol(x2, Decl(mappedTypesArraysTuples.ts, 66, 7))
>all : Symbol(all, Decl(mappedTypesArraysTuples.ts, 60, 55))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 64, 12))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 64, 22))
let x3 = all(a, b, c);
>x3 : Symbol(x3, Decl(mappedTypesArraysTuples.ts, 59, 7))
>all : Symbol(all, Decl(mappedTypesArraysTuples.ts, 52, 55))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 56, 12))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 56, 22))
>c : Symbol(c, Decl(mappedTypesArraysTuples.ts, 56, 42))
>x3 : Symbol(x3, Decl(mappedTypesArraysTuples.ts, 67, 7))
>all : Symbol(all, Decl(mappedTypesArraysTuples.ts, 60, 55))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 64, 12))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 64, 22))
>c : Symbol(c, Decl(mappedTypesArraysTuples.ts, 64, 42))
let x4 = all(a, b, c, d);
>x4 : Symbol(x4, Decl(mappedTypesArraysTuples.ts, 60, 7))
>all : Symbol(all, Decl(mappedTypesArraysTuples.ts, 52, 55))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 56, 12))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 56, 22))
>c : Symbol(c, Decl(mappedTypesArraysTuples.ts, 56, 42))
>d : Symbol(d, Decl(mappedTypesArraysTuples.ts, 56, 55))
>x4 : Symbol(x4, Decl(mappedTypesArraysTuples.ts, 68, 7))
>all : Symbol(all, Decl(mappedTypesArraysTuples.ts, 60, 55))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 64, 12))
>b : Symbol(b, Decl(mappedTypesArraysTuples.ts, 64, 22))
>c : Symbol(c, Decl(mappedTypesArraysTuples.ts, 64, 42))
>d : Symbol(d, Decl(mappedTypesArraysTuples.ts, 64, 55))
}
function f2<T extends any[]>(a: Boxified<T>) {
>f2 : Symbol(f2, Decl(mappedTypesArraysTuples.ts, 61, 1))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 63, 12))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 63, 29))
>f2 : Symbol(f2, Decl(mappedTypesArraysTuples.ts, 69, 1))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 71, 12))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 71, 29))
>Boxified : Symbol(Boxified, Decl(mappedTypesArraysTuples.ts, 0, 27))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 63, 12))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 71, 12))
let x: Box<any> | undefined = a.pop();
>x : Symbol(x, Decl(mappedTypesArraysTuples.ts, 64, 7))
>x : Symbol(x, Decl(mappedTypesArraysTuples.ts, 72, 7))
>Box : Symbol(Box, Decl(mappedTypesArraysTuples.ts, 0, 0))
>a.pop : Symbol(Array.pop, Decl(lib.es5.d.ts, --, --))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 63, 29))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 71, 29))
>pop : Symbol(Array.pop, Decl(lib.es5.d.ts, --, --))
let y: Box<any>[] = a.concat(a);
>y : Symbol(y, Decl(mappedTypesArraysTuples.ts, 65, 7))
>y : Symbol(y, Decl(mappedTypesArraysTuples.ts, 73, 7))
>Box : Symbol(Box, Decl(mappedTypesArraysTuples.ts, 0, 0))
>a.concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 63, 29))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 71, 29))
>concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 63, 29))
>a : Symbol(a, Decl(mappedTypesArraysTuples.ts, 71, 29))
}
// Repro from #26163
type ElementType<T> = T extends Array<infer U> ? U : never;
>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 66, 1))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 70, 17))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 70, 17))
>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 74, 1))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 78, 17))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 78, 17))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
>U : Symbol(U, Decl(mappedTypesArraysTuples.ts, 70, 43))
>U : Symbol(U, Decl(mappedTypesArraysTuples.ts, 70, 43))
>U : Symbol(U, Decl(mappedTypesArraysTuples.ts, 78, 43))
>U : Symbol(U, Decl(mappedTypesArraysTuples.ts, 78, 43))
type Mapped<T> = { [K in keyof T]: T[K] };
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 70, 59))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 71, 12))
>K : Symbol(K, Decl(mappedTypesArraysTuples.ts, 71, 20))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 71, 12))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 71, 12))
>K : Symbol(K, Decl(mappedTypesArraysTuples.ts, 71, 20))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 78, 59))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 79, 12))
>K : Symbol(K, Decl(mappedTypesArraysTuples.ts, 79, 20))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 79, 12))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 79, 12))
>K : Symbol(K, Decl(mappedTypesArraysTuples.ts, 79, 20))
type F<T> = ElementType<Mapped<T>>;
>F : Symbol(F, Decl(mappedTypesArraysTuples.ts, 71, 42))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 73, 7))
>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 66, 1))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 70, 59))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 73, 7))
>F : Symbol(F, Decl(mappedTypesArraysTuples.ts, 79, 42))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 81, 7))
>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 74, 1))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 78, 59))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 81, 7))
type R1 = F<[string, number, boolean]>; // string | number | boolean
>R1 : Symbol(R1, Decl(mappedTypesArraysTuples.ts, 73, 35))
>F : Symbol(F, Decl(mappedTypesArraysTuples.ts, 71, 42))
>R1 : Symbol(R1, Decl(mappedTypesArraysTuples.ts, 81, 35))
>F : Symbol(F, Decl(mappedTypesArraysTuples.ts, 79, 42))
type R2 = ElementType<Mapped<[string, number, boolean]>>; // string | number | boolean
>R2 : Symbol(R2, Decl(mappedTypesArraysTuples.ts, 74, 39))
>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 66, 1))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 70, 59))
>R2 : Symbol(R2, Decl(mappedTypesArraysTuples.ts, 82, 39))
>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 74, 1))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 78, 59))
// Repro from #26163
declare function acceptArray(arr: any[]): void;
>acceptArray : Symbol(acceptArray, Decl(mappedTypesArraysTuples.ts, 75, 57))
>arr : Symbol(arr, Decl(mappedTypesArraysTuples.ts, 79, 29))
>acceptArray : Symbol(acceptArray, Decl(mappedTypesArraysTuples.ts, 83, 57))
>arr : Symbol(arr, Decl(mappedTypesArraysTuples.ts, 87, 29))
declare function mapArray<T extends any[]>(arr: T): Mapped<T>;
>mapArray : Symbol(mapArray, Decl(mappedTypesArraysTuples.ts, 79, 47))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 80, 26))
>arr : Symbol(arr, Decl(mappedTypesArraysTuples.ts, 80, 43))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 80, 26))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 70, 59))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 80, 26))
>mapArray : Symbol(mapArray, Decl(mappedTypesArraysTuples.ts, 87, 47))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 88, 26))
>arr : Symbol(arr, Decl(mappedTypesArraysTuples.ts, 88, 43))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 88, 26))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 78, 59))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 88, 26))
function acceptMappedArray<T extends any[]>(arr: T) {
>acceptMappedArray : Symbol(acceptMappedArray, Decl(mappedTypesArraysTuples.ts, 80, 62))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 81, 27))
>arr : Symbol(arr, Decl(mappedTypesArraysTuples.ts, 81, 44))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 81, 27))
>acceptMappedArray : Symbol(acceptMappedArray, Decl(mappedTypesArraysTuples.ts, 88, 62))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 89, 27))
>arr : Symbol(arr, Decl(mappedTypesArraysTuples.ts, 89, 44))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 89, 27))
acceptArray(mapArray(arr));
>acceptArray : Symbol(acceptArray, Decl(mappedTypesArraysTuples.ts, 75, 57))
>mapArray : Symbol(mapArray, Decl(mappedTypesArraysTuples.ts, 79, 47))
>arr : Symbol(arr, Decl(mappedTypesArraysTuples.ts, 81, 44))
>acceptArray : Symbol(acceptArray, Decl(mappedTypesArraysTuples.ts, 83, 57))
>mapArray : Symbol(mapArray, Decl(mappedTypesArraysTuples.ts, 87, 47))
>arr : Symbol(arr, Decl(mappedTypesArraysTuples.ts, 89, 44))
}
// Repro from #26163
type Unconstrained<T> = ElementType<Mapped<T>>;
>Unconstrained : Symbol(Unconstrained, Decl(mappedTypesArraysTuples.ts, 83, 1))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 87, 19))
>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 66, 1))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 70, 59))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 87, 19))
>Unconstrained : Symbol(Unconstrained, Decl(mappedTypesArraysTuples.ts, 91, 1))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 95, 19))
>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 74, 1))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 78, 59))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 95, 19))
type T1 = Unconstrained<[string, number, boolean]>; // string | number | boolean
>T1 : Symbol(T1, Decl(mappedTypesArraysTuples.ts, 87, 47))
>Unconstrained : Symbol(Unconstrained, Decl(mappedTypesArraysTuples.ts, 83, 1))
>T1 : Symbol(T1, Decl(mappedTypesArraysTuples.ts, 95, 47))
>Unconstrained : Symbol(Unconstrained, Decl(mappedTypesArraysTuples.ts, 91, 1))
type Constrained<T extends any[]> = ElementType<Mapped<T>>;
>Constrained : Symbol(Constrained, Decl(mappedTypesArraysTuples.ts, 88, 51))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 90, 17))
>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 66, 1))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 70, 59))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 90, 17))
>Constrained : Symbol(Constrained, Decl(mappedTypesArraysTuples.ts, 96, 51))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 98, 17))
>ElementType : Symbol(ElementType, Decl(mappedTypesArraysTuples.ts, 74, 1))
>Mapped : Symbol(Mapped, Decl(mappedTypesArraysTuples.ts, 78, 59))
>T : Symbol(T, Decl(mappedTypesArraysTuples.ts, 98, 17))
type T2 = Constrained<[string, number, boolean]>; // string | number | boolean
>T2 : Symbol(T2, Decl(mappedTypesArraysTuples.ts, 90, 59))
>Constrained : Symbol(Constrained, Decl(mappedTypesArraysTuples.ts, 88, 51))
>T2 : Symbol(T2, Decl(mappedTypesArraysTuples.ts, 98, 59))
>Constrained : Symbol(Constrained, Decl(mappedTypesArraysTuples.ts, 96, 51))

View file

@ -25,13 +25,13 @@ type T12 = Required<string[]>;
>T12 : string[]
type T13 = Boxified<ReadonlyArray<string>>;
>T13 : ReadonlyArray<Box<string>>
>T13 : readonly Box<string>[]
type T14 = Partial<ReadonlyArray<string>>;
>T14 : ReadonlyArray<string | undefined>
>T14 : readonly (string | undefined)[]
type T15 = Required<ReadonlyArray<string>>;
>T15 : ReadonlyArray<string>
>T15 : readonly string[]
type T20 = Boxified<(string | undefined)[]>;
>T20 : Box<string | undefined>[]
@ -43,13 +43,13 @@ type T22 = Required<(string | undefined)[]>;
>T22 : string[]
type T23 = Boxified<ReadonlyArray<string | undefined>>;
>T23 : ReadonlyArray<Box<string | undefined>>
>T23 : readonly Box<string | undefined>[]
type T24 = Partial<ReadonlyArray<string | undefined>>;
>T24 : ReadonlyArray<string | undefined>
>T24 : readonly (string | undefined)[]
type T25 = Required<ReadonlyArray<string | undefined>>;
>T25 : ReadonlyArray<string>
>T25 : readonly string[]
type T30 = Boxified<Partial<string[]>>;
>T30 : Box<string | undefined>[]
@ -66,7 +66,25 @@ type B = { b: string };
>b : string
type T40 = Boxified<A | A[] | ReadonlyArray<A> | [A, B] | string | string[]>;
>T40 : string | Box<string>[] | Boxified<A> | Box<A>[] | ReadonlyArray<Box<A>> | [Box<A>, Box<B>]
>T40 : string | Box<string>[] | Boxified<A> | Box<A>[] | readonly Box<A>[] | [Box<A>, Box<B>]
type ReadWrite<T> = { -readonly [P in keyof T] : T[P] };
>ReadWrite : ReadWrite<T>
type T50 = Readonly<string[]>;
>T50 : readonly string[]
type T51 = Readonly<[number, number]>;
>T51 : readonly [number, number]
type T52 = Partial<Readonly<string[]>>;
>T52 : readonly (string | undefined)[]
type T53 = Readonly<Partial<string[]>>;
>T53 : readonly (string | undefined)[]
type T54 = ReadWrite<Required<T53>>;
>T54 : string[]
declare function unboxify<T>(x: Boxified<T>): T;
>unboxify : <T>(x: Boxified<T>) => T

View file

@ -117,6 +117,6 @@ function f(x = 0, b = false) {
>1 : 1
}
function f2(_: ReadonlyArray<number>): void {}
>f2 : (_: ReadonlyArray<number>) => void
>_ : ReadonlyArray<number>
>f2 : (_: readonly number[]) => void
>_ : readonly number[]

View file

@ -1,5 +1,5 @@
tests/cases/compiler/objectFreeze.ts(9,1): error TS2322: Type 'string' is not assignable to type 'number'.
tests/cases/compiler/objectFreeze.ts(9,1): error TS2542: Index signature in type 'ReadonlyArray<number>' only permits reading.
tests/cases/compiler/objectFreeze.ts(9,1): error TS2542: Index signature in type 'readonly number[]' only permits reading.
tests/cases/compiler/objectFreeze.ts(12,3): error TS2540: Cannot assign to 'b' because it is a read-only property.
@ -16,7 +16,7 @@ tests/cases/compiler/objectFreeze.ts(12,3): error TS2540: Cannot assign to 'b' b
~~~~
!!! error TS2322: Type 'string' is not assignable to type 'number'.
~~~~
!!! error TS2542: Index signature in type 'ReadonlyArray<number>' only permits reading.
!!! error TS2542: Index signature in type 'readonly number[]' only permits reading.
const o = Object.freeze({ a: 1, b: "string" });
o.b = o.a.toString();

View file

@ -2,9 +2,9 @@
const f = Object.freeze(function foo(a: number, b: string) { return false; });
>f : (a: number, b: string) => false
>Object.freeze(function foo(a: number, b: string) { return false; }) : (a: number, b: string) => false
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object.freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>function foo(a: number, b: string) { return false; } : (a: number, b: string) => false
>foo : (a: number, b: string) => false
>a : number
@ -26,9 +26,9 @@ class C { constructor(a: number) { } }
const c = Object.freeze(C);
>c : typeof C
>Object.freeze(C) : typeof C
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object.freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>C : typeof C
new c(1);
@ -37,11 +37,11 @@ new c(1);
>1 : 1
const a = Object.freeze([1, 2, 3]);
>a : ReadonlyArray<number>
>Object.freeze([1, 2, 3]) : ReadonlyArray<number>
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>a : readonly number[]
>Object.freeze([1, 2, 3]) : readonly number[]
>Object.freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>[1, 2, 3] : number[]
>1 : 1
>2 : 2
@ -50,21 +50,21 @@ const a = Object.freeze([1, 2, 3]);
a[0] = a[2].toString();
>a[0] = a[2].toString() : string
>a[0] : number
>a : ReadonlyArray<number>
>a : readonly number[]
>0 : 0
>a[2].toString() : string
>a[2].toString : (radix?: number) => string
>a[2] : number
>a : ReadonlyArray<number>
>a : readonly number[]
>2 : 2
>toString : (radix?: number) => string
const o = Object.freeze({ a: 1, b: "string" });
>o : Readonly<{ a: number; b: string; }>
>Object.freeze({ a: 1, b: "string" }) : Readonly<{ a: number; b: string; }>
>Object.freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object.freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>Object : ObjectConstructor
>freeze : { <T>(a: T[]): ReadonlyArray<T>; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>freeze : { <T>(a: T[]): readonly T[]; <T extends Function>(f: T): T; <T>(o: T): Readonly<T>; }
>{ a: 1, b: "string" } : { a: number; b: string; }
>a : number
>1 : 1

View file

@ -0,0 +1,60 @@
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(9,12): error TS1354: 'readonly' type modifier is only permitted on array and tuple types.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(10,15): error TS1354: 'readonly' type modifier is only permitted on array and tuple types.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(11,12): error TS1354: 'readonly' type modifier is only permitted on array and tuple types.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(14,5): error TS2740: Type 'readonly string[]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(16,5): error TS2740: Type 'readonly [string, string]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(20,5): error TS2739: Type 'string[]' is missing the following properties from type '[string, string]': 0, 1
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(21,5): error TS2740: Type 'readonly string[]' is missing the following properties from type '[string, string]': 0, 1, pop, push, and 5 more.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(22,5): error TS2740: Type 'readonly [string, string]' is missing the following properties from type '[string, string]': pop, push, reverse, shift, and 3 more.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(23,5): error TS2739: Type 'string[]' is missing the following properties from type 'readonly [string, string]': 0, 1
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(24,5): error TS2739: Type 'readonly string[]' is missing the following properties from type 'readonly [string, string]': 0, 1
==== tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts (10 errors) ====
type T10 = string[];
type T11 = Array<string>;
type T12 = readonly string[];
type T13 = ReadonlyArray<string>;
type T20 = [number, number];
type T21 = readonly [number, number];
type T30 = readonly string; // Error
~~~~~~~~
!!! error TS1354: 'readonly' type modifier is only permitted on array and tuple types.
type T31<T> = readonly T; // Error
~~~~~~~~
!!! error TS1354: 'readonly' type modifier is only permitted on array and tuple types.
type T32 = readonly readonly string[]; // Error
~~~~~~~~
!!! error TS1354: 'readonly' type modifier is only permitted on array and tuple types.
function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) {
ma = ra; // Error
~~
!!! error TS2740: Type 'readonly string[]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more.
ma = mt;
ma = rt; // Error
~~
!!! error TS2740: Type 'readonly [string, string]' is missing the following properties from type 'string[]': pop, push, reverse, shift, and 3 more.
ra = ma;
ra = mt;
ra = rt;
mt = ma; // Error
~~
!!! error TS2739: Type 'string[]' is missing the following properties from type '[string, string]': 0, 1
mt = ra; // Error
~~
!!! error TS2740: Type 'readonly string[]' is missing the following properties from type '[string, string]': 0, 1, pop, push, and 5 more.
mt = rt; // Error
~~
!!! error TS2740: Type 'readonly [string, string]' is missing the following properties from type '[string, string]': pop, push, reverse, shift, and 3 more.
rt = ma; // Error
~~
!!! error TS2739: Type 'string[]' is missing the following properties from type 'readonly [string, string]': 0, 1
rt = ra; // Error
~~
!!! error TS2739: Type 'readonly string[]' is missing the following properties from type 'readonly [string, string]': 0, 1
rt = mt;
}

View file

@ -0,0 +1,58 @@
//// [readonlyArraysAndTuples.ts]
type T10 = string[];
type T11 = Array<string>;
type T12 = readonly string[];
type T13 = ReadonlyArray<string>;
type T20 = [number, number];
type T21 = readonly [number, number];
type T30 = readonly string; // Error
type T31<T> = readonly T; // Error
type T32 = readonly readonly string[]; // Error
function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) {
ma = ra; // Error
ma = mt;
ma = rt; // Error
ra = ma;
ra = mt;
ra = rt;
mt = ma; // Error
mt = ra; // Error
mt = rt; // Error
rt = ma; // Error
rt = ra; // Error
rt = mt;
}
//// [readonlyArraysAndTuples.js]
"use strict";
function f1(ma, ra, mt, rt) {
ma = ra; // Error
ma = mt;
ma = rt; // Error
ra = ma;
ra = mt;
ra = rt;
mt = ma; // Error
mt = ra; // Error
mt = rt; // Error
rt = ma; // Error
rt = ra; // Error
rt = mt;
}
//// [readonlyArraysAndTuples.d.ts]
declare type T10 = string[];
declare type T11 = Array<string>;
declare type T12 = readonly string[];
declare type T13 = ReadonlyArray<string>;
declare type T20 = [number, number];
declare type T21 = readonly [number, number];
declare type T30 = readonly string;
declare type T31<T> = readonly T;
declare type T32 = readonly readonly string[];
declare function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]): void;

View file

@ -0,0 +1,88 @@
=== tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts ===
type T10 = string[];
>T10 : Symbol(T10, Decl(readonlyArraysAndTuples.ts, 0, 0))
type T11 = Array<string>;
>T11 : Symbol(T11, Decl(readonlyArraysAndTuples.ts, 0, 20))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
type T12 = readonly string[];
>T12 : Symbol(T12, Decl(readonlyArraysAndTuples.ts, 1, 25))
type T13 = ReadonlyArray<string>;
>T13 : Symbol(T13, Decl(readonlyArraysAndTuples.ts, 2, 29))
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
type T20 = [number, number];
>T20 : Symbol(T20, Decl(readonlyArraysAndTuples.ts, 3, 33))
type T21 = readonly [number, number];
>T21 : Symbol(T21, Decl(readonlyArraysAndTuples.ts, 5, 28))
type T30 = readonly string; // Error
>T30 : Symbol(T30, Decl(readonlyArraysAndTuples.ts, 6, 37))
type T31<T> = readonly T; // Error
>T31 : Symbol(T31, Decl(readonlyArraysAndTuples.ts, 8, 27))
>T : Symbol(T, Decl(readonlyArraysAndTuples.ts, 9, 9))
>T : Symbol(T, Decl(readonlyArraysAndTuples.ts, 9, 9))
type T32 = readonly readonly string[]; // Error
>T32 : Symbol(T32, Decl(readonlyArraysAndTuples.ts, 9, 25))
function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) {
>f1 : Symbol(f1, Decl(readonlyArraysAndTuples.ts, 10, 38))
>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12))
>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25))
>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48))
>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70))
ma = ra; // Error
>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12))
>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25))
ma = mt;
>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12))
>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48))
ma = rt; // Error
>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12))
>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70))
ra = ma;
>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25))
>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12))
ra = mt;
>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25))
>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48))
ra = rt;
>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25))
>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70))
mt = ma; // Error
>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48))
>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12))
mt = ra; // Error
>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48))
>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25))
mt = rt; // Error
>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48))
>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70))
rt = ma; // Error
>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70))
>ma : Symbol(ma, Decl(readonlyArraysAndTuples.ts, 12, 12))
rt = ra; // Error
>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70))
>ra : Symbol(ra, Decl(readonlyArraysAndTuples.ts, 12, 25))
rt = mt;
>rt : Symbol(rt, Decl(readonlyArraysAndTuples.ts, 12, 70))
>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 12, 48))
}

View file

@ -0,0 +1,96 @@
=== tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts ===
type T10 = string[];
>T10 : string[]
type T11 = Array<string>;
>T11 : string[]
type T12 = readonly string[];
>T12 : readonly string[]
type T13 = ReadonlyArray<string>;
>T13 : readonly string[]
type T20 = [number, number];
>T20 : [number, number]
type T21 = readonly [number, number];
>T21 : readonly [number, number]
type T30 = readonly string; // Error
>T30 : string
type T31<T> = readonly T; // Error
>T31 : T
type T32 = readonly readonly string[]; // Error
>T32 : readonly string[]
function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) {
>f1 : (ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) => void
>ma : string[]
>ra : readonly string[]
>mt : [string, string]
>rt : readonly [string, string]
ma = ra; // Error
>ma = ra : readonly string[]
>ma : string[]
>ra : readonly string[]
ma = mt;
>ma = mt : [string, string]
>ma : string[]
>mt : [string, string]
ma = rt; // Error
>ma = rt : readonly [string, string]
>ma : string[]
>rt : readonly [string, string]
ra = ma;
>ra = ma : string[]
>ra : readonly string[]
>ma : string[]
ra = mt;
>ra = mt : [string, string]
>ra : readonly string[]
>mt : [string, string]
ra = rt;
>ra = rt : readonly [string, string]
>ra : readonly string[]
>rt : readonly [string, string]
mt = ma; // Error
>mt = ma : string[]
>mt : [string, string]
>ma : string[]
mt = ra; // Error
>mt = ra : readonly string[]
>mt : [string, string]
>ra : readonly string[]
mt = rt; // Error
>mt = rt : readonly [string, string]
>mt : [string, string]
>rt : readonly [string, string]
rt = ma; // Error
>rt = ma : string[]
>rt : readonly [string, string]
>ma : string[]
rt = ra; // Error
>rt = ra : readonly string[]
>rt : readonly [string, string]
>ra : readonly string[]
rt = mt;
>rt = mt : [string, string]
>rt : readonly [string, string]
>mt : [string, string]
}

View file

@ -0,0 +1,62 @@
//// [readonlyArraysAndTuples2.ts]
type T10 = string[];
type T11 = Array<string>;
type T12 = readonly string[];
type T13 = ReadonlyArray<string>;
type T20 = [number, number];
type T21 = readonly [number, number];
declare function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]): readonly [string, string];
declare const someDec: any;
class A {
@someDec
j: readonly string[] = [];
@someDec
k: readonly [string, number] = ['foo', 42];
}
//// [readonlyArraysAndTuples2.js]
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var A = /** @class */ (function () {
function A() {
this.j = [];
this.k = ['foo', 42];
}
__decorate([
someDec,
__metadata("design:type", Array)
], A.prototype, "j");
__decorate([
someDec,
__metadata("design:type", Array)
], A.prototype, "k");
return A;
}());
//// [readonlyArraysAndTuples2.d.ts]
declare type T10 = string[];
declare type T11 = Array<string>;
declare type T12 = readonly string[];
declare type T13 = ReadonlyArray<string>;
declare type T20 = [number, number];
declare type T21 = readonly [number, number];
declare function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]): readonly [string, string];
declare const someDec: any;
declare class A {
j: readonly string[];
k: readonly [string, number];
}

View file

@ -0,0 +1,47 @@
=== tests/cases/conformance/types/tuple/readonlyArraysAndTuples2.ts ===
type T10 = string[];
>T10 : Symbol(T10, Decl(readonlyArraysAndTuples2.ts, 0, 0))
type T11 = Array<string>;
>T11 : Symbol(T11, Decl(readonlyArraysAndTuples2.ts, 0, 20))
>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --))
type T12 = readonly string[];
>T12 : Symbol(T12, Decl(readonlyArraysAndTuples2.ts, 1, 25))
type T13 = ReadonlyArray<string>;
>T13 : Symbol(T13, Decl(readonlyArraysAndTuples2.ts, 2, 29))
>ReadonlyArray : Symbol(ReadonlyArray, Decl(lib.es5.d.ts, --, --))
type T20 = [number, number];
>T20 : Symbol(T20, Decl(readonlyArraysAndTuples2.ts, 3, 33))
type T21 = readonly [number, number];
>T21 : Symbol(T21, Decl(readonlyArraysAndTuples2.ts, 5, 28))
declare function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]): readonly [string, string];
>f1 : Symbol(f1, Decl(readonlyArraysAndTuples2.ts, 6, 37))
>ma : Symbol(ma, Decl(readonlyArraysAndTuples2.ts, 8, 20))
>ra : Symbol(ra, Decl(readonlyArraysAndTuples2.ts, 8, 33))
>mt : Symbol(mt, Decl(readonlyArraysAndTuples2.ts, 8, 56))
>rt : Symbol(rt, Decl(readonlyArraysAndTuples2.ts, 8, 78))
declare const someDec: any;
>someDec : Symbol(someDec, Decl(readonlyArraysAndTuples2.ts, 10, 13))
class A {
>A : Symbol(A, Decl(readonlyArraysAndTuples2.ts, 10, 27))
@someDec
>someDec : Symbol(someDec, Decl(readonlyArraysAndTuples2.ts, 10, 13))
j: readonly string[] = [];
>j : Symbol(A.j, Decl(readonlyArraysAndTuples2.ts, 12, 9))
@someDec
>someDec : Symbol(someDec, Decl(readonlyArraysAndTuples2.ts, 10, 13))
k: readonly [string, number] = ['foo', 42];
>k : Symbol(A.k, Decl(readonlyArraysAndTuples2.ts, 14, 28))
}

View file

@ -0,0 +1,49 @@
=== tests/cases/conformance/types/tuple/readonlyArraysAndTuples2.ts ===
type T10 = string[];
>T10 : string[]
type T11 = Array<string>;
>T11 : string[]
type T12 = readonly string[];
>T12 : readonly string[]
type T13 = ReadonlyArray<string>;
>T13 : readonly string[]
type T20 = [number, number];
>T20 : [number, number]
type T21 = readonly [number, number];
>T21 : readonly [number, number]
declare function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]): readonly [string, string];
>f1 : (ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) => readonly [string, string]
>ma : string[]
>ra : readonly string[]
>mt : [string, string]
>rt : readonly [string, string]
declare const someDec: any;
>someDec : any
class A {
>A : A
@someDec
>someDec : any
j: readonly string[] = [];
>j : readonly string[]
>[] : never[]
@someDec
>someDec : any
k: readonly [string, number] = ['foo', 42];
>k : readonly [string, number]
>['foo', 42] : [string, number]
>'foo' : "foo"
>42 : 42
}

View file

@ -0,0 +1,40 @@
tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts(8,5): error TS2556: Expected 2 arguments, but got 0 or more.
tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts(20,5): error TS2554: Expected 2 arguments, but got 3.
tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts(25,5): error TS2542: Index signature in type 'readonly string[]' only permits reading.
==== tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts (3 errors) ====
function f0(a: string, b: string) {
f0(a, b);
f1(a, b);
f2(a, b);
}
function f1(...args: readonly string[]) {
f0(...args); // Error
~~~~~~~~~~~
!!! error TS2556: Expected 2 arguments, but got 0 or more.
!!! related TS6210 tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts:1:13: An argument for 'a' was not provided.
f1('abc', 'def');
f1('abc', ...args);
f1(...args);
}
function f2(...args: readonly [string, string]) {
f0(...args);
f1('abc', 'def');
f1('abc', ...args);
f1(...args);
f2('abc', 'def');
f2('abc', ...args); // Error
~~~~~~~~~~~~~~~~~~
!!! error TS2554: Expected 2 arguments, but got 3.
f2(...args);
}
function f4(...args: readonly string[]) {
args[0] = 'abc'; // Error
~~~~~~~
!!! error TS2542: Index signature in type 'readonly string[]' only permits reading.
}

View file

@ -0,0 +1,73 @@
//// [readonlyRestParameters.ts]
function f0(a: string, b: string) {
f0(a, b);
f1(a, b);
f2(a, b);
}
function f1(...args: readonly string[]) {
f0(...args); // Error
f1('abc', 'def');
f1('abc', ...args);
f1(...args);
}
function f2(...args: readonly [string, string]) {
f0(...args);
f1('abc', 'def');
f1('abc', ...args);
f1(...args);
f2('abc', 'def');
f2('abc', ...args); // Error
f2(...args);
}
function f4(...args: readonly string[]) {
args[0] = 'abc'; // Error
}
//// [readonlyRestParameters.js]
"use strict";
function f0(a, b) {
f0(a, b);
f1(a, b);
f2(a, b);
}
function f1() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
f0.apply(void 0, args); // Error
f1('abc', 'def');
f1.apply(void 0, ['abc'].concat(args));
f1.apply(void 0, args);
}
function f2() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
f0.apply(void 0, args);
f1('abc', 'def');
f1.apply(void 0, ['abc'].concat(args));
f1.apply(void 0, args);
f2('abc', 'def');
f2.apply(void 0, ['abc'].concat(args)); // Error
f2.apply(void 0, args);
}
function f4() {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
args[0] = 'abc'; // Error
}
//// [readonlyRestParameters.d.ts]
declare function f0(a: string, b: string): void;
declare function f1(...args: readonly string[]): void;
declare function f2(...args: readonly [string, string]): void;
declare function f4(...args: readonly string[]): void;

View file

@ -0,0 +1,81 @@
=== tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts ===
function f0(a: string, b: string) {
>f0 : Symbol(f0, Decl(readonlyRestParameters.ts, 0, 0))
>a : Symbol(a, Decl(readonlyRestParameters.ts, 0, 12))
>b : Symbol(b, Decl(readonlyRestParameters.ts, 0, 22))
f0(a, b);
>f0 : Symbol(f0, Decl(readonlyRestParameters.ts, 0, 0))
>a : Symbol(a, Decl(readonlyRestParameters.ts, 0, 12))
>b : Symbol(b, Decl(readonlyRestParameters.ts, 0, 22))
f1(a, b);
>f1 : Symbol(f1, Decl(readonlyRestParameters.ts, 4, 1))
>a : Symbol(a, Decl(readonlyRestParameters.ts, 0, 12))
>b : Symbol(b, Decl(readonlyRestParameters.ts, 0, 22))
f2(a, b);
>f2 : Symbol(f2, Decl(readonlyRestParameters.ts, 11, 1))
>a : Symbol(a, Decl(readonlyRestParameters.ts, 0, 12))
>b : Symbol(b, Decl(readonlyRestParameters.ts, 0, 22))
}
function f1(...args: readonly string[]) {
>f1 : Symbol(f1, Decl(readonlyRestParameters.ts, 4, 1))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 6, 12))
f0(...args); // Error
>f0 : Symbol(f0, Decl(readonlyRestParameters.ts, 0, 0))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 6, 12))
f1('abc', 'def');
>f1 : Symbol(f1, Decl(readonlyRestParameters.ts, 4, 1))
f1('abc', ...args);
>f1 : Symbol(f1, Decl(readonlyRestParameters.ts, 4, 1))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 6, 12))
f1(...args);
>f1 : Symbol(f1, Decl(readonlyRestParameters.ts, 4, 1))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 6, 12))
}
function f2(...args: readonly [string, string]) {
>f2 : Symbol(f2, Decl(readonlyRestParameters.ts, 11, 1))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 13, 12))
f0(...args);
>f0 : Symbol(f0, Decl(readonlyRestParameters.ts, 0, 0))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 13, 12))
f1('abc', 'def');
>f1 : Symbol(f1, Decl(readonlyRestParameters.ts, 4, 1))
f1('abc', ...args);
>f1 : Symbol(f1, Decl(readonlyRestParameters.ts, 4, 1))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 13, 12))
f1(...args);
>f1 : Symbol(f1, Decl(readonlyRestParameters.ts, 4, 1))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 13, 12))
f2('abc', 'def');
>f2 : Symbol(f2, Decl(readonlyRestParameters.ts, 11, 1))
f2('abc', ...args); // Error
>f2 : Symbol(f2, Decl(readonlyRestParameters.ts, 11, 1))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 13, 12))
f2(...args);
>f2 : Symbol(f2, Decl(readonlyRestParameters.ts, 11, 1))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 13, 12))
}
function f4(...args: readonly string[]) {
>f4 : Symbol(f4, Decl(readonlyRestParameters.ts, 21, 1))
>args : Symbol(args, Decl(readonlyRestParameters.ts, 23, 12))
args[0] = 'abc'; // Error
>args : Symbol(args, Decl(readonlyRestParameters.ts, 23, 12))
}

View file

@ -0,0 +1,116 @@
=== tests/cases/conformance/es6/restParameters/readonlyRestParameters.ts ===
function f0(a: string, b: string) {
>f0 : (a: string, b: string) => void
>a : string
>b : string
f0(a, b);
>f0(a, b) : void
>f0 : (a: string, b: string) => void
>a : string
>b : string
f1(a, b);
>f1(a, b) : void
>f1 : (...args: readonly string[]) => void
>a : string
>b : string
f2(a, b);
>f2(a, b) : void
>f2 : (args_0: string, args_1: string) => void
>a : string
>b : string
}
function f1(...args: readonly string[]) {
>f1 : (...args: readonly string[]) => void
>args : readonly string[]
f0(...args); // Error
>f0(...args) : void
>f0 : (a: string, b: string) => void
>...args : string
>args : readonly string[]
f1('abc', 'def');
>f1('abc', 'def') : void
>f1 : (...args: readonly string[]) => void
>'abc' : "abc"
>'def' : "def"
f1('abc', ...args);
>f1('abc', ...args) : void
>f1 : (...args: readonly string[]) => void
>'abc' : "abc"
>...args : string
>args : readonly string[]
f1(...args);
>f1(...args) : void
>f1 : (...args: readonly string[]) => void
>...args : string
>args : readonly string[]
}
function f2(...args: readonly [string, string]) {
>f2 : (args_0: string, args_1: string) => void
>args : readonly [string, string]
f0(...args);
>f0(...args) : void
>f0 : (a: string, b: string) => void
>...args : string
>args : readonly [string, string]
f1('abc', 'def');
>f1('abc', 'def') : void
>f1 : (...args: readonly string[]) => void
>'abc' : "abc"
>'def' : "def"
f1('abc', ...args);
>f1('abc', ...args) : void
>f1 : (...args: readonly string[]) => void
>'abc' : "abc"
>...args : string
>args : readonly [string, string]
f1(...args);
>f1(...args) : void
>f1 : (...args: readonly string[]) => void
>...args : string
>args : readonly [string, string]
f2('abc', 'def');
>f2('abc', 'def') : void
>f2 : (args_0: string, args_1: string) => void
>'abc' : "abc"
>'def' : "def"
f2('abc', ...args); // Error
>f2('abc', ...args) : void
>f2 : (args_0: string, args_1: string) => void
>'abc' : "abc"
>...args : string
>args : readonly [string, string]
f2(...args);
>f2(...args) : void
>f2 : (args_0: string, args_1: string) => void
>...args : string
>args : readonly [string, string]
}
function f4(...args: readonly string[]) {
>f4 : (...args: readonly string[]) => void
>args : readonly string[]
args[0] = 'abc'; // Error
>args[0] = 'abc' : "abc"
>args[0] : string
>args : readonly string[]
>0 : 0
>'abc' : "abc"
}

View file

@ -97,13 +97,13 @@ const x11 = f3(never, fo, fx); // "def"
// Repro from #21112
declare function foo<T>(a: ReadonlyArray<T>): T;
>foo : <T>(a: ReadonlyArray<T>) => T
>a : ReadonlyArray<T>
>foo : <T>(a: readonly T[]) => T
>a : readonly T[]
let x = foo([]); // never
>x : never
>foo([]) : never
>foo : <T>(a: ReadonlyArray<T>) => T
>foo : <T>(a: readonly T[]) => T
>[] : never[]
// Modified repros from #26127

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,29 @@
// @strict: true
// @declaration: true
function f0(a: string, b: string) {
f0(a, b);
f1(a, b);
f2(a, b);
}
function f1(...args: readonly string[]) {
f0(...args); // Error
f1('abc', 'def');
f1('abc', ...args);
f1(...args);
}
function f2(...args: readonly [string, string]) {
f0(...args);
f1('abc', 'def');
f1('abc', ...args);
f1(...args);
f2('abc', 'def');
f2('abc', ...args); // Error
f2(...args);
}
function f4(...args: readonly string[]) {
args[0] = 'abc'; // Error
}

View file

@ -30,6 +30,14 @@ type B = { b: string };
type T40 = Boxified<A | A[] | ReadonlyArray<A> | [A, B] | string | string[]>;
type ReadWrite<T> = { -readonly [P in keyof T] : T[P] };
type T50 = Readonly<string[]>;
type T51 = Readonly<[number, number]>;
type T52 = Partial<Readonly<string[]>>;
type T53 = Readonly<Partial<string[]>>;
type T54 = ReadWrite<Required<T53>>;
declare function unboxify<T>(x: Boxified<T>): T;
declare let x10: [Box<number>, Box<string>, ...Box<boolean>[]];

View file

@ -0,0 +1,29 @@
// @strict: true
// @declaration: true
type T10 = string[];
type T11 = Array<string>;
type T12 = readonly string[];
type T13 = ReadonlyArray<string>;
type T20 = [number, number];
type T21 = readonly [number, number];
type T30 = readonly string; // Error
type T31<T> = readonly T; // Error
type T32 = readonly readonly string[]; // Error
function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]) {
ma = ra; // Error
ma = mt;
ma = rt; // Error
ra = ma;
ra = mt;
ra = rt;
mt = ma; // Error
mt = ra; // Error
mt = rt; // Error
rt = ma; // Error
rt = ra; // Error
rt = mt;
}

View file

@ -0,0 +1,23 @@
// @strict: true
// @declaration: true
// @emitDecoratorMetadata: true
// @experimentalDecorators: true
type T10 = string[];
type T11 = Array<string>;
type T12 = readonly string[];
type T13 = ReadonlyArray<string>;
type T20 = [number, number];
type T21 = readonly [number, number];
declare function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]): readonly [string, string];
declare const someDec: any;
class A {
@someDec
j: readonly string[] = [];
@someDec
k: readonly [string, number] = ['foo', 42];
}