diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a745a3841282f..75ab23407b3d0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -572,8 +572,10 @@ namespace ts { } const enum MappedTypeModifiers { - Readonly = 1 << 0, - Optional = 1 << 1, + IncludeReadonly = 1 << 0, + ExcludeReadonly = 1 << 1, + IncludeOptional = 1 << 2, + ExcludeOptional = 1 << 3, } const enum ExpandingFlags { @@ -2967,11 +2969,10 @@ namespace ts { function createMappedTypeNodeFromType(type: MappedType) { Debug.assert(!!(type.flags & TypeFlags.Object)); - const readonlyToken = type.declaration && type.declaration.readonlyToken ? createToken(SyntaxKind.ReadonlyKeyword) : undefined; - const questionToken = type.declaration && type.declaration.questionToken ? createToken(SyntaxKind.QuestionToken) : undefined; + const readonlyToken = type.declaration.readonlyToken ? createToken(type.declaration.readonlyToken.kind) : undefined; + const questionToken = type.declaration.questionToken ? createToken(type.declaration.questionToken.kind) : undefined; const typeParameterNode = typeParameterToDeclaration(getTypeParameterFromMappedType(type), context, getConstraintTypeFromMappedType(type)); const templateTypeNode = typeToTypeNodeHelper(getTemplateTypeFromMappedType(type), context); - const mappedTypeNode = createMappedTypeNode(readonlyToken, typeParameterNode, questionToken, templateTypeNode); return setEmitFlags(mappedTypeNode, EmitFlags.SingleLine); } @@ -5819,8 +5820,9 @@ namespace ts { function resolveReverseMappedTypeMembers(type: ReverseMappedType) { const indexInfo = getIndexInfoOfType(type.source, IndexKind.String); - const readonlyMask = type.mappedType.declaration.readonlyToken ? false : true; - const optionalMask = type.mappedType.declaration.questionToken ? 0 : SymbolFlags.Optional; + const modifiers = getMappedTypeModifiers(type.mappedType); + const readonlyMask = modifiers & MappedTypeModifiers.IncludeReadonly ? false : true; + const optionalMask = modifiers & MappedTypeModifiers.IncludeOptional ? 0 : SymbolFlags.Optional; const stringIndexInfo = indexInfo && createIndexInfo(inferReverseMappedType(indexInfo.type, type.mappedType), readonlyMask && indexInfo.isReadonly); const members = createSymbolTable(); for (const prop of getPropertiesOfType(type.source)) { @@ -5846,8 +5848,7 @@ namespace ts { const constraintType = getConstraintTypeFromMappedType(type); const templateType = getTemplateTypeFromMappedType(type.target || type); const modifiersType = getApparentType(getModifiersTypeFromMappedType(type)); // The 'T' in 'keyof T' - const templateReadonly = !!type.declaration.readonlyToken; - const templateOptional = !!type.declaration.questionToken; + const templateModifiers = getMappedTypeModifiers(type); const constraintDeclaration = type.declaration.typeParameter.constraint; if (constraintDeclaration.kind === SyntaxKind.TypeOperator && (constraintDeclaration).operator === SyntaxKind.KeyOfKeyword) { @@ -5888,10 +5889,17 @@ namespace ts { if (t.flags & TypeFlags.StringLiteral) { const propName = escapeLeadingUnderscores((t).value); const modifiersProp = getPropertyOfType(modifiersType, propName); - const isOptional = templateOptional || !!(modifiersProp && modifiersProp.flags & SymbolFlags.Optional); - const checkFlags = templateReadonly || modifiersProp && isReadonlySymbol(modifiersProp) ? CheckFlags.Readonly : 0; - const prop = createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName, checkFlags); - prop.type = propType; + const isOptional = !!(templateModifiers & MappedTypeModifiers.IncludeOptional || + !(templateModifiers & MappedTypeModifiers.ExcludeOptional) && modifiersProp && modifiersProp.flags & SymbolFlags.Optional); + const isReadonly = !!(templateModifiers & MappedTypeModifiers.IncludeReadonly || + !(templateModifiers & MappedTypeModifiers.ExcludeReadonly) && modifiersProp && isReadonlySymbol(modifiersProp)); + const prop = createSymbol(SymbolFlags.Property | (isOptional ? SymbolFlags.Optional : 0), propName, isReadonly ? CheckFlags.Readonly : 0); + // When creating an optional property in strictNullChecks mode, if 'undefined' isn't assignable to the + // type, we include 'undefined' in the type. Similarly, when creating a non-optional property in strictNullChecks + // mode, if the underlying property is optional we remove 'undefined' from the type. + prop.type = strictNullChecks && isOptional && !isTypeAssignableTo(undefinedType, propType) ? getOptionalType(propType) : + strictNullChecks && !isOptional && modifiersProp && modifiersProp.flags & SymbolFlags.Optional ? getTypeWithFacts(propType, TypeFacts.NEUndefined) : + propType; if (propertySymbol) { prop.syntheticOrigin = propertySymbol; prop.declarations = propertySymbol.declarations; @@ -5900,7 +5908,7 @@ namespace ts { members.set(propName, prop); } else if (t.flags & (TypeFlags.Any | TypeFlags.String)) { - stringIndexInfo = createIndexInfo(propType, templateReadonly); + stringIndexInfo = createIndexInfo(propType, !!(templateModifiers & MappedTypeModifiers.IncludeReadonly)); } } } @@ -5918,7 +5926,7 @@ namespace ts { function getTemplateTypeFromMappedType(type: MappedType) { return type.templateType || (type.templateType = type.declaration.type ? - instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!type.declaration.questionToken), type.mapper || identityMapper) : + instantiateType(addOptionality(getTypeFromTypeNode(type.declaration.type), !!(getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional)), type.mapper || identityMapper) : unknownType); } @@ -5946,18 +5954,24 @@ namespace ts { } function getMappedTypeModifiers(type: MappedType): MappedTypeModifiers { - return (type.declaration.readonlyToken ? MappedTypeModifiers.Readonly : 0) | - (type.declaration.questionToken ? MappedTypeModifiers.Optional : 0); + const declaration = type.declaration; + return (declaration.readonlyToken ? declaration.readonlyToken.kind === SyntaxKind.MinusToken ? MappedTypeModifiers.ExcludeReadonly : MappedTypeModifiers.IncludeReadonly : 0) | + (declaration.questionToken ? declaration.questionToken.kind === SyntaxKind.MinusToken ? MappedTypeModifiers.ExcludeOptional : MappedTypeModifiers.IncludeOptional : 0); + } + + function getMappedTypeOptionality(type: MappedType): number { + const modifiers = getMappedTypeModifiers(type); + return modifiers & MappedTypeModifiers.ExcludeOptional ? -1 : modifiers & MappedTypeModifiers.IncludeOptional ? 1 : 0; } - function getCombinedMappedTypeModifiers(type: MappedType): MappedTypeModifiers { + function getCombinedMappedTypeOptionality(type: MappedType): number { + const optionality = getMappedTypeOptionality(type); const modifiersType = getModifiersTypeFromMappedType(type); - return getMappedTypeModifiers(type) | - (isGenericMappedType(modifiersType) ? getMappedTypeModifiers(modifiersType) : 0); + return optionality || (isGenericMappedType(modifiersType) ? getMappedTypeOptionality(modifiersType) : 0); } function isPartialMappedType(type: Type) { - return getObjectFlags(type) & ObjectFlags.Mapped && !!(type).declaration.questionToken; + return !!(getObjectFlags(type) & ObjectFlags.Mapped && getMappedTypeModifiers(type) & MappedTypeModifiers.IncludeOptional); } function isGenericMappedType(type: Type): type is MappedType { @@ -9960,7 +9974,7 @@ namespace ts { if (target.flags & TypeFlags.TypeParameter) { // A source type { [P in keyof T]: X } is related to a target type T if X is related to T[P]. if (getObjectFlags(source) & ObjectFlags.Mapped && getConstraintTypeFromMappedType(source) === getIndexType(target)) { - if (!(source).declaration.questionToken) { + if (!(getMappedTypeModifiers(source) & MappedTypeModifiers.IncludeOptional)) { const templateType = getTemplateTypeFromMappedType(source); const indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(source)); if (result = isRelatedTo(templateType, indexedAccessType, reportErrors)) { @@ -9999,6 +10013,8 @@ namespace ts { else if (isGenericMappedType(target)) { // A source type T is related to a target type { [P in X]: T[P] } const template = getTemplateTypeFromMappedType(target); + const modifiers = getMappedTypeModifiers(target); + if (!(modifiers & MappedTypeModifiers.ExcludeOptional)) { if (template.flags & TypeFlags.IndexedAccess && (template).objectType === source && (template).indexType === getTypeParameterFromMappedType(target)) { return Ternary.True; @@ -10013,6 +10029,7 @@ namespace ts { } } } + } if (source.flags & TypeFlags.TypeParameter) { let constraint = getConstraintForRelation(source); @@ -10162,8 +10179,7 @@ namespace ts { function mappedTypeRelatedTo(source: MappedType, target: MappedType, reportErrors: boolean): Ternary { const modifiersRelated = relation === comparableRelation || ( relation === identityRelation ? getMappedTypeModifiers(source) === getMappedTypeModifiers(target) : - !(getCombinedMappedTypeModifiers(source) & MappedTypeModifiers.Optional) || - getCombinedMappedTypeModifiers(target) & MappedTypeModifiers.Optional); + getCombinedMappedTypeOptionality(source) <= getCombinedMappedTypeOptionality(target)); if (modifiersRelated) { let result: Ternary; if (result = isRelatedTo(getConstraintTypeFromMappedType(target), getConstraintTypeFromMappedType(source), reportErrors)) { @@ -20345,7 +20361,7 @@ namespace ts { const indexType = (type).indexType; if (isTypeAssignableTo(indexType, getIndexType(objectType))) { if (accessNode.kind === SyntaxKind.ElementAccessExpression && isAssignmentTarget(accessNode) && - getObjectFlags(objectType) & ObjectFlags.Mapped && (objectType).declaration.readonlyToken) { + getObjectFlags(objectType) & ObjectFlags.Mapped && getMappedTypeModifiers(objectType) & MappedTypeModifiers.IncludeReadonly) { error(accessNode, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType)); } return type; diff --git a/src/compiler/declarationEmitter.ts b/src/compiler/declarationEmitter.ts index 24646ff31eb44..f18a32889aa87 100644 --- a/src/compiler/declarationEmitter.ts +++ b/src/compiler/declarationEmitter.ts @@ -593,7 +593,9 @@ namespace ts { writeLine(); increaseIndent(); if (node.readonlyToken) { - write("readonly "); + write(node.readonlyToken.kind === SyntaxKind.PlusToken ? "+readonly " : + node.readonlyToken.kind === SyntaxKind.MinusToken ? "-readonly " : + "readonly "); } write("["); writeEntityName(node.typeParameter.name); @@ -601,7 +603,9 @@ namespace ts { emitType(node.typeParameter.constraint); write("]"); if (node.questionToken) { - write("?"); + write(node.questionToken.kind === SyntaxKind.PlusToken ? "+?" : + node.questionToken.kind === SyntaxKind.MinusToken ? "-?" : + "?"); } write(": "); emitType(node.type); diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 3c9866b353694..735e0d67f472e 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -1251,14 +1251,20 @@ namespace ts { } if (node.readonlyToken) { emit(node.readonlyToken); + if (node.readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) { + writeKeyword("readonly"); + } writeSpace(); } - writePunctuation("["); pipelineEmitWithNotification(EmitHint.MappedTypeParameter, node.typeParameter); writePunctuation("]"); - - emitIfPresent(node.questionToken); + if (node.questionToken) { + emit(node.questionToken); + if (node.questionToken.kind !== SyntaxKind.QuestionToken) { + writePunctuation("?"); + } + } writePunctuation(":"); writeSpace(); emit(node.type); diff --git a/src/compiler/factory.ts b/src/compiler/factory.ts index 165c70b37e610..8166196e469b1 100644 --- a/src/compiler/factory.ts +++ b/src/compiler/factory.ts @@ -804,7 +804,7 @@ namespace ts { : node; } - export function createMappedTypeNode(readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode { + export function createMappedTypeNode(readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode { const node = createSynthesizedNode(SyntaxKind.MappedType) as MappedTypeNode; node.readonlyToken = readonlyToken; node.typeParameter = typeParameter; @@ -813,7 +813,7 @@ namespace ts { return node; } - export function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode { + export function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode { return node.readonlyToken !== readonlyToken || node.typeParameter !== typeParameter || node.questionToken !== questionToken diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 3209f234f85e5..b71983b978379 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -695,7 +695,7 @@ namespace ts { else if (token() === SyntaxKind.OpenBraceToken || lookAhead(() => token() === SyntaxKind.StringLiteral)) { result.jsonObject = parseObjectLiteralExpression(); - sourceFile.endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, /*reportAtCurrentPosition*/ false, Diagnostics.Unexpected_token); + sourceFile.endOfFileToken = parseExpectedToken(SyntaxKind.EndOfFileToken, Diagnostics.Unexpected_token); } else { parseExpected(SyntaxKind.OpenBraceToken); @@ -1135,10 +1135,10 @@ namespace ts { return undefined; } - function parseExpectedToken(t: TKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Token; - function parseExpectedToken(t: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node { + function parseExpectedToken(t: TKind, diagnosticMessage?: DiagnosticMessage, arg0?: any): Token; + function parseExpectedToken(t: SyntaxKind, diagnosticMessage?: DiagnosticMessage, arg0?: any): Node { return parseOptionalToken(t) || - createMissingNode(t, reportAtCurrentPosition, diagnosticMessage, arg0); + createMissingNode(t, /*reportAtCurrentPosition*/ false, diagnosticMessage || Diagnostics._0_expected, arg0 || tokenToString(t)); } function parseTokenNode(): T { @@ -2113,7 +2113,7 @@ namespace ts { literal = parseTemplateMiddleOrTemplateTail(); } else { - literal = parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)); + literal = parseExpectedToken(SyntaxKind.TemplateTail, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken)); } span.literal = literal; @@ -2607,6 +2607,9 @@ namespace ts { function isStartOfMappedType() { nextToken(); + if (token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { + return nextToken() === SyntaxKind.ReadonlyKeyword; + } if (token() === SyntaxKind.ReadonlyKeyword) { nextToken(); } @@ -2624,11 +2627,21 @@ namespace ts { function parseMappedType() { const node = createNode(SyntaxKind.MappedType); parseExpected(SyntaxKind.OpenBraceToken); - node.readonlyToken = parseOptionalToken(SyntaxKind.ReadonlyKeyword); + if (token() === SyntaxKind.ReadonlyKeyword || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { + node.readonlyToken = parseTokenNode(); + if (node.readonlyToken.kind !== SyntaxKind.ReadonlyKeyword) { + parseExpectedToken(SyntaxKind.ReadonlyKeyword); + } + } parseExpected(SyntaxKind.OpenBracketToken); node.typeParameter = parseMappedTypeParameter(); parseExpected(SyntaxKind.CloseBracketToken); - node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken); + if (token() === SyntaxKind.QuestionToken || token() === SyntaxKind.PlusToken || token() === SyntaxKind.MinusToken) { + node.questionToken = parseTokenNode(); + if (node.questionToken.kind !== SyntaxKind.QuestionToken) { + parseExpectedToken(SyntaxKind.QuestionToken); + } + } node.type = parseTypeAnnotation(); parseSemicolon(); parseExpected(SyntaxKind.CloseBraceToken); @@ -3242,7 +3255,7 @@ namespace ts { node.parameters = createNodeArray([parameter], parameter.pos, parameter.end); - node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>"); + node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); node.body = parseArrowFunctionExpressionBody(/*isAsync*/ !!asyncModifier); return addJSDocComment(finishNode(node)); @@ -3273,7 +3286,7 @@ namespace ts { // If we have an arrow, then try to parse the body. Even if not, try to parse if we // have an opening brace, just in case we're in an error state. const lastToken = token(); - arrowFunction.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, "=>"); + arrowFunction.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken); arrowFunction.body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken) ? parseArrowFunctionExpressionBody(isAsync) : parseIdentifier(); @@ -3539,8 +3552,7 @@ namespace ts { node.condition = leftOperand; node.questionToken = questionToken; node.whenTrue = doOutsideOfContext(disallowInAndDecoratorContext, parseAssignmentExpressionOrHigher); - node.colonToken = parseExpectedToken(SyntaxKind.ColonToken, /*reportAtCurrentPosition*/ false, - Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); + node.colonToken = parseExpectedToken(SyntaxKind.ColonToken); node.whenFalse = nodeIsPresent(node.colonToken) ? parseAssignmentExpressionOrHigher() : createMissingNode(SyntaxKind.Identifier, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.ColonToken)); @@ -4014,7 +4026,7 @@ namespace ts { // If it wasn't then just try to parse out a '.' and report an error. const node = createNode(SyntaxKind.PropertyAccessExpression, expression.pos); node.expression = expression; - parseExpectedToken(SyntaxKind.DotToken, /*reportAtCurrentPosition*/ false, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); + parseExpectedToken(SyntaxKind.DotToken, Diagnostics.super_must_be_followed_by_an_argument_list_or_member_access); node.name = parseRightSideOfDot(/*allowIdentifierNames*/ true); return finishNode(node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b74ed84e809e7..f4a4fb8a79e34 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -661,6 +661,8 @@ namespace ts { export type AtToken = Token; export type ReadonlyToken = Token; export type AwaitKeywordToken = Token; + export type PlusToken = Token; + export type MinusToken = Token; export type Modifier = Token @@ -1158,9 +1160,9 @@ namespace ts { export interface MappedTypeNode extends TypeNode, Declaration { kind: SyntaxKind.MappedType; - readonlyToken?: ReadonlyToken; + readonlyToken?: ReadonlyToken | PlusToken | MinusToken; typeParameter: TypeParameterDeclaration; - questionToken?: QuestionToken; + questionToken?: QuestionToken | PlusToken | MinusToken; type?: TypeNode; } diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 0f773e787869e..bab3bc67d3871 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1317,6 +1317,13 @@ type Partial = { [P in keyof T]?: T[P]; }; +/** + * Make all properties in T required + */ +type Required = { + [P in keyof T]-?: T[P]; +}; + /** * Make all properties in T readonly */ diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 6ef91a9a057d2..9b49636e62354 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -477,6 +477,8 @@ declare namespace ts { type AtToken = Token; type ReadonlyToken = Token; type AwaitKeywordToken = Token; + type PlusToken = Token; + type MinusToken = Token; type Modifier = Token | Token | Token | Token | Token | Token | Token | Token | Token | Token | Token; type ModifiersArray = NodeArray; interface Identifier extends PrimaryExpression, Declaration { @@ -766,9 +768,9 @@ declare namespace ts { } interface MappedTypeNode extends TypeNode, Declaration { kind: SyntaxKind.MappedType; - readonlyToken?: ReadonlyToken; + readonlyToken?: ReadonlyToken | PlusToken | MinusToken; typeParameter: TypeParameterDeclaration; - questionToken?: QuestionToken; + questionToken?: QuestionToken | PlusToken | MinusToken; type?: TypeNode; } interface LiteralTypeNode extends TypeNode { @@ -3515,8 +3517,8 @@ declare namespace ts { function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode; function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; - function createMappedTypeNode(readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode; - function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode; + function createMappedTypeNode(readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; function createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; function createObjectBindingPattern(elements: ReadonlyArray): ObjectBindingPattern; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index b6877639e5c22..b513bb2b7bfe5 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -477,6 +477,8 @@ declare namespace ts { type AtToken = Token; type ReadonlyToken = Token; type AwaitKeywordToken = Token; + type PlusToken = Token; + type MinusToken = Token; type Modifier = Token | Token | Token | Token | Token | Token | Token | Token | Token | Token | Token; type ModifiersArray = NodeArray; interface Identifier extends PrimaryExpression, Declaration { @@ -766,9 +768,9 @@ declare namespace ts { } interface MappedTypeNode extends TypeNode, Declaration { kind: SyntaxKind.MappedType; - readonlyToken?: ReadonlyToken; + readonlyToken?: ReadonlyToken | PlusToken | MinusToken; typeParameter: TypeParameterDeclaration; - questionToken?: QuestionToken; + questionToken?: QuestionToken | PlusToken | MinusToken; type?: TypeNode; } interface LiteralTypeNode extends TypeNode { @@ -3462,8 +3464,8 @@ declare namespace ts { function updateTypeOperatorNode(node: TypeOperatorNode, type: TypeNode): TypeOperatorNode; function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; function updateIndexedAccessTypeNode(node: IndexedAccessTypeNode, objectType: TypeNode, indexType: TypeNode): IndexedAccessTypeNode; - function createMappedTypeNode(readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode; - function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | undefined, type: TypeNode | undefined): MappedTypeNode; + function createMappedTypeNode(readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; + function updateMappedTypeNode(node: MappedTypeNode, readonlyToken: ReadonlyToken | PlusToken | MinusToken | undefined, typeParameter: TypeParameterDeclaration, questionToken: QuestionToken | PlusToken | MinusToken | undefined, type: TypeNode | undefined): MappedTypeNode; function createLiteralTypeNode(literal: LiteralTypeNode["literal"]): LiteralTypeNode; function updateLiteralTypeNode(node: LiteralTypeNode, literal: LiteralTypeNode["literal"]): LiteralTypeNode; function createObjectBindingPattern(elements: ReadonlyArray): ObjectBindingPattern; diff --git a/tests/baselines/reference/mappedTypes6.errors.txt b/tests/baselines/reference/mappedTypes6.errors.txt new file mode 100644 index 0000000000000..843a59eecb5fb --- /dev/null +++ b/tests/baselines/reference/mappedTypes6.errors.txt @@ -0,0 +1,195 @@ +tests/cases/conformance/types/mapped/mappedTypes6.ts(23,5): error TS2322: Type 'T' is not assignable to type 'Required'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(24,5): error TS2322: Type 'Partial' is not assignable to type 'Required'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(27,5): error TS2322: Type 'Partial' is not assignable to type 'T'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(37,5): error TS2322: Type 'Required' is not assignable to type 'Denullified'. + Type 'T[P]' is not assignable to type 'NonNullable'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(38,5): error TS2322: Type 'T' is not assignable to type 'Denullified'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(39,5): error TS2322: Type 'Partial' is not assignable to type 'Denullified'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(42,5): error TS2322: Type 'T' is not assignable to type 'Required'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(43,5): error TS2322: Type 'Partial' is not assignable to type 'Required'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(47,5): error TS2322: Type 'Partial' is not assignable to type 'T'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(56,5): error TS2322: Type '{}' is not assignable to type 'Denullified'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(57,5): error TS2322: Type '{}' is not assignable to type 'Required'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(58,5): error TS2322: Type '{}' is not assignable to type 'T'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(92,1): error TS2322: Type '{ a: number; }' is not assignable to type 'Foo'. + Property 'b' is missing in type '{ a: number; }'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(104,1): error TS2322: Type '{ a: number; }' is not assignable to type 'Required'. + Property 'b' is missing in type '{ a: number; }'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(105,1): error TS2322: Type '{ a: number; b: number; }' is not assignable to type 'Required'. + Property 'c' is missing in type '{ a: number; b: number; }'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(106,1): error TS2322: Type '{ a: number; b: number; c: number; }' is not assignable to type 'Required'. + Property 'd' is missing in type '{ a: number; b: number; c: number; }'. +tests/cases/conformance/types/mapped/mappedTypes6.ts(116,4): error TS2540: Cannot assign to 'b' because it is a constant or a read-only property. +tests/cases/conformance/types/mapped/mappedTypes6.ts(119,4): error TS2540: Cannot assign to 'a' because it is a constant or a read-only property. +tests/cases/conformance/types/mapped/mappedTypes6.ts(120,4): error TS2540: Cannot assign to 'b' because it is a constant or a read-only property. + + +==== tests/cases/conformance/types/mapped/mappedTypes6.ts (19 errors) ==== + type T00 = { [P in keyof T]: T[P] }; + type T01 = { [P in keyof T]?: T[P] }; + type T02 = { [P in keyof T]+?: T[P] }; + type T03 = { [P in keyof T]-?: T[P] }; + + type T04 = { readonly [P in keyof T]: T[P] }; + type T05 = { readonly [P in keyof T]?: T[P] }; + type T06 = { readonly [P in keyof T]+?: T[P] }; + type T07 = { readonly [P in keyof T]-?: T[P] }; + + type T08 = { +readonly [P in keyof T]: T[P] }; + type T09 = { +readonly [P in keyof T]?: T[P] }; + type T10 = { +readonly [P in keyof T]+?: T[P] }; + type T11 = { +readonly [P in keyof T]-?: T[P] }; + + type T12 = { -readonly [P in keyof T]: T[P] }; + type T13 = { -readonly [P in keyof T]?: T[P] }; + type T14 = { -readonly [P in keyof T]+?: T[P] }; + type T15 = { -readonly [P in keyof T]-?: T[P] }; + + function f1(x: Required, y: T, z: Partial) { + x = x; + x = y; // Error + ~ +!!! error TS2322: Type 'T' is not assignable to type 'Required'. + x = z; // Error + ~ +!!! error TS2322: Type 'Partial' is not assignable to type 'Required'. + y = x; + y = y; + y = z; // Error + ~ +!!! error TS2322: Type 'Partial' is not assignable to type 'T'. + z = x; + z = y; + z = z; + } + + type Denullified = { [P in keyof T]-?: NonNullable }; + + function f2(w: Denullified, x: Required, y: T, z: Partial) { + w = w; + w = x; // Error + ~ +!!! error TS2322: Type 'Required' is not assignable to type 'Denullified'. +!!! error TS2322: Type 'T[P]' is not assignable to type 'NonNullable'. + w = y; // Error + ~ +!!! error TS2322: Type 'T' is not assignable to type 'Denullified'. + w = z; // Error + ~ +!!! error TS2322: Type 'Partial' is not assignable to type 'Denullified'. + x = w; + x = x; + x = y; // Error + ~ +!!! error TS2322: Type 'T' is not assignable to type 'Required'. + x = z; // Error + ~ +!!! error TS2322: Type 'Partial' is not assignable to type 'Required'. + y = w; + y = x; + y = y; + y = z; // Error + ~ +!!! error TS2322: Type 'Partial' is not assignable to type 'T'. + z = w; + z = x; + z = y; + z = z; + } + + + function f3(w: Denullified, x: Required, y: T, z: Partial) { + w = {}; // Error + ~ +!!! error TS2322: Type '{}' is not assignable to type 'Denullified'. + x = {}; // Error + ~ +!!! error TS2322: Type '{}' is not assignable to type 'Required'. + y = {}; // Error + ~ +!!! error TS2322: Type '{}' is not assignable to type 'T'. + z = {}; + } + + type Readwrite = { + -readonly [P in keyof T]: T[P]; + } + + function f10(x: Readonly, y: T, z: Readwrite) { + x = x; + x = y; + x = z; + y = x; + y = y; + y = z; + z = x; + z = y; + z = z; + } + + type Foo = { + a: number; + b: number | undefined; + c?: number; + d?: number | undefined; + } + + declare let x1: Foo; + + x1.a; // number + x1.b; // number | undefined + x1.c; // number | undefined + x1.d; // number | undefined + + x1 = { a: 1 }; // Error + ~~ +!!! error TS2322: Type '{ a: number; }' is not assignable to type 'Foo'. +!!! error TS2322: Property 'b' is missing in type '{ a: number; }'. + x1 = { a: 1, b: 1 }; + x1 = { a: 1, b: 1, c: 1 }; + x1 = { a: 1, b: 1, c: 1, d: 1 }; + + declare let x2: Required; + + x1.a; // number + x1.b; // number | undefined + x1.c; // number + x1.d; // number + + x2 = { a: 1 }; // Error + ~~ +!!! error TS2322: Type '{ a: number; }' is not assignable to type 'Required'. +!!! error TS2322: Property 'b' is missing in type '{ a: number; }'. + x2 = { a: 1, b: 1 }; // Error + ~~ +!!! error TS2322: Type '{ a: number; b: number; }' is not assignable to type 'Required'. +!!! error TS2322: Property 'c' is missing in type '{ a: number; b: number; }'. + x2 = { a: 1, b: 1, c: 1 }; // Error + ~~ +!!! error TS2322: Type '{ a: number; b: number; c: number; }' is not assignable to type 'Required'. +!!! error TS2322: Property 'd' is missing in type '{ a: number; b: number; c: number; }'. + x2 = { a: 1, b: 1, c: 1, d: 1 }; + + type Bar = { + a: number; + readonly b: number; + } + + declare let x3: Bar; + x3.a = 1; + x3.b = 1; // Error + ~ +!!! error TS2540: Cannot assign to 'b' because it is a constant or a read-only property. + + declare let x4: Readonly; + x4.a = 1; // Error + ~ +!!! error TS2540: Cannot assign to 'a' because it is a constant or a read-only property. + x4.b = 1; // Error + ~ +!!! error TS2540: Cannot assign to 'b' because it is a constant or a read-only property. + + declare let x5: Readwrite; + x5.a = 1; + x5.b = 1; + \ No newline at end of file diff --git a/tests/baselines/reference/mappedTypes6.js b/tests/baselines/reference/mappedTypes6.js new file mode 100644 index 0000000000000..b24d210eb75be --- /dev/null +++ b/tests/baselines/reference/mappedTypes6.js @@ -0,0 +1,273 @@ +//// [mappedTypes6.ts] +type T00 = { [P in keyof T]: T[P] }; +type T01 = { [P in keyof T]?: T[P] }; +type T02 = { [P in keyof T]+?: T[P] }; +type T03 = { [P in keyof T]-?: T[P] }; + +type T04 = { readonly [P in keyof T]: T[P] }; +type T05 = { readonly [P in keyof T]?: T[P] }; +type T06 = { readonly [P in keyof T]+?: T[P] }; +type T07 = { readonly [P in keyof T]-?: T[P] }; + +type T08 = { +readonly [P in keyof T]: T[P] }; +type T09 = { +readonly [P in keyof T]?: T[P] }; +type T10 = { +readonly [P in keyof T]+?: T[P] }; +type T11 = { +readonly [P in keyof T]-?: T[P] }; + +type T12 = { -readonly [P in keyof T]: T[P] }; +type T13 = { -readonly [P in keyof T]?: T[P] }; +type T14 = { -readonly [P in keyof T]+?: T[P] }; +type T15 = { -readonly [P in keyof T]-?: T[P] }; + +function f1(x: Required, y: T, z: Partial) { + x = x; + x = y; // Error + x = z; // Error + y = x; + y = y; + y = z; // Error + z = x; + z = y; + z = z; +} + +type Denullified = { [P in keyof T]-?: NonNullable }; + +function f2(w: Denullified, x: Required, y: T, z: Partial) { + w = w; + w = x; // Error + w = y; // Error + w = z; // Error + x = w; + x = x; + x = y; // Error + x = z; // Error + y = w; + y = x; + y = y; + y = z; // Error + z = w; + z = x; + z = y; + z = z; +} + + +function f3(w: Denullified, x: Required, y: T, z: Partial) { + w = {}; // Error + x = {}; // Error + y = {}; // Error + z = {}; +} + +type Readwrite = { + -readonly [P in keyof T]: T[P]; +} + +function f10(x: Readonly, y: T, z: Readwrite) { + x = x; + x = y; + x = z; + y = x; + y = y; + y = z; + z = x; + z = y; + z = z; +} + +type Foo = { + a: number; + b: number | undefined; + c?: number; + d?: number | undefined; +} + +declare let x1: Foo; + +x1.a; // number +x1.b; // number | undefined +x1.c; // number | undefined +x1.d; // number | undefined + +x1 = { a: 1 }; // Error +x1 = { a: 1, b: 1 }; +x1 = { a: 1, b: 1, c: 1 }; +x1 = { a: 1, b: 1, c: 1, d: 1 }; + +declare let x2: Required; + +x1.a; // number +x1.b; // number | undefined +x1.c; // number +x1.d; // number + +x2 = { a: 1 }; // Error +x2 = { a: 1, b: 1 }; // Error +x2 = { a: 1, b: 1, c: 1 }; // Error +x2 = { a: 1, b: 1, c: 1, d: 1 }; + +type Bar = { + a: number; + readonly b: number; +} + +declare let x3: Bar; +x3.a = 1; +x3.b = 1; // Error + +declare let x4: Readonly; +x4.a = 1; // Error +x4.b = 1; // Error + +declare let x5: Readwrite; +x5.a = 1; +x5.b = 1; + + +//// [mappedTypes6.js] +"use strict"; +function f1(x, y, z) { + x = x; + x = y; // Error + x = z; // Error + y = x; + y = y; + y = z; // Error + z = x; + z = y; + z = z; +} +function f2(w, x, y, z) { + w = w; + w = x; // Error + w = y; // Error + w = z; // Error + x = w; + x = x; + x = y; // Error + x = z; // Error + y = w; + y = x; + y = y; + y = z; // Error + z = w; + z = x; + z = y; + z = z; +} +function f3(w, x, y, z) { + w = {}; // Error + x = {}; // Error + y = {}; // Error + z = {}; +} +function f10(x, y, z) { + x = x; + x = y; + x = z; + y = x; + y = y; + y = z; + z = x; + z = y; + z = z; +} +x1.a; // number +x1.b; // number | undefined +x1.c; // number | undefined +x1.d; // number | undefined +x1 = { a: 1 }; // Error +x1 = { a: 1, b: 1 }; +x1 = { a: 1, b: 1, c: 1 }; +x1 = { a: 1, b: 1, c: 1, d: 1 }; +x1.a; // number +x1.b; // number | undefined +x1.c; // number +x1.d; // number +x2 = { a: 1 }; // Error +x2 = { a: 1, b: 1 }; // Error +x2 = { a: 1, b: 1, c: 1 }; // Error +x2 = { a: 1, b: 1, c: 1, d: 1 }; +x3.a = 1; +x3.b = 1; // Error +x4.a = 1; // Error +x4.b = 1; // Error +x5.a = 1; +x5.b = 1; + + +//// [mappedTypes6.d.ts] +declare type T00 = { + [P in keyof T]: T[P]; +}; +declare type T01 = { + [P in keyof T]?: T[P]; +}; +declare type T02 = { + [P in keyof T]+?: T[P]; +}; +declare type T03 = { + [P in keyof T]-?: T[P]; +}; +declare type T04 = { + readonly [P in keyof T]: T[P]; +}; +declare type T05 = { + readonly [P in keyof T]?: T[P]; +}; +declare type T06 = { + readonly [P in keyof T]+?: T[P]; +}; +declare type T07 = { + readonly [P in keyof T]-?: T[P]; +}; +declare type T08 = { + +readonly [P in keyof T]: T[P]; +}; +declare type T09 = { + +readonly [P in keyof T]?: T[P]; +}; +declare type T10 = { + +readonly [P in keyof T]+?: T[P]; +}; +declare type T11 = { + +readonly [P in keyof T]-?: T[P]; +}; +declare type T12 = { + -readonly [P in keyof T]: T[P]; +}; +declare type T13 = { + -readonly [P in keyof T]?: T[P]; +}; +declare type T14 = { + -readonly [P in keyof T]+?: T[P]; +}; +declare type T15 = { + -readonly [P in keyof T]-?: T[P]; +}; +declare function f1(x: Required, y: T, z: Partial): void; +declare type Denullified = { + [P in keyof T]-?: NonNullable; +}; +declare function f2(w: Denullified, x: Required, y: T, z: Partial): void; +declare function f3(w: Denullified, x: Required, y: T, z: Partial): void; +declare type Readwrite = { + -readonly [P in keyof T]: T[P]; +}; +declare function f10(x: Readonly, y: T, z: Readwrite): void; +declare type Foo = { + a: number; + b: number | undefined; + c?: number; + d?: number | undefined; +}; +declare let x1: Foo; +declare let x2: Required; +declare type Bar = { + a: number; + readonly b: number; +}; +declare let x3: Bar; +declare let x4: Readonly; +declare let x5: Readwrite; diff --git a/tests/baselines/reference/mappedTypes6.symbols b/tests/baselines/reference/mappedTypes6.symbols new file mode 100644 index 0000000000000..7cebcda184e46 --- /dev/null +++ b/tests/baselines/reference/mappedTypes6.symbols @@ -0,0 +1,519 @@ +=== tests/cases/conformance/types/mapped/mappedTypes6.ts === +type T00 = { [P in keyof T]: T[P] }; +>T00 : Symbol(T00, Decl(mappedTypes6.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypes6.ts, 0, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 0, 17)) +>T : Symbol(T, Decl(mappedTypes6.ts, 0, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 0, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 0, 17)) + +type T01 = { [P in keyof T]?: T[P] }; +>T01 : Symbol(T01, Decl(mappedTypes6.ts, 0, 39)) +>T : Symbol(T, Decl(mappedTypes6.ts, 1, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 1, 17)) +>T : Symbol(T, Decl(mappedTypes6.ts, 1, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 1, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 1, 17)) + +type T02 = { [P in keyof T]+?: T[P] }; +>T02 : Symbol(T02, Decl(mappedTypes6.ts, 1, 40)) +>T : Symbol(T, Decl(mappedTypes6.ts, 2, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 2, 17)) +>T : Symbol(T, Decl(mappedTypes6.ts, 2, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 2, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 2, 17)) + +type T03 = { [P in keyof T]-?: T[P] }; +>T03 : Symbol(T03, Decl(mappedTypes6.ts, 2, 41)) +>T : Symbol(T, Decl(mappedTypes6.ts, 3, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 3, 17)) +>T : Symbol(T, Decl(mappedTypes6.ts, 3, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 3, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 3, 17)) + +type T04 = { readonly [P in keyof T]: T[P] }; +>T04 : Symbol(T04, Decl(mappedTypes6.ts, 3, 41)) +>T : Symbol(T, Decl(mappedTypes6.ts, 5, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 5, 26)) +>T : Symbol(T, Decl(mappedTypes6.ts, 5, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 5, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 5, 26)) + +type T05 = { readonly [P in keyof T]?: T[P] }; +>T05 : Symbol(T05, Decl(mappedTypes6.ts, 5, 48)) +>T : Symbol(T, Decl(mappedTypes6.ts, 6, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 6, 26)) +>T : Symbol(T, Decl(mappedTypes6.ts, 6, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 6, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 6, 26)) + +type T06 = { readonly [P in keyof T]+?: T[P] }; +>T06 : Symbol(T06, Decl(mappedTypes6.ts, 6, 49)) +>T : Symbol(T, Decl(mappedTypes6.ts, 7, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 7, 26)) +>T : Symbol(T, Decl(mappedTypes6.ts, 7, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 7, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 7, 26)) + +type T07 = { readonly [P in keyof T]-?: T[P] }; +>T07 : Symbol(T07, Decl(mappedTypes6.ts, 7, 50)) +>T : Symbol(T, Decl(mappedTypes6.ts, 8, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 8, 26)) +>T : Symbol(T, Decl(mappedTypes6.ts, 8, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 8, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 8, 26)) + +type T08 = { +readonly [P in keyof T]: T[P] }; +>T08 : Symbol(T08, Decl(mappedTypes6.ts, 8, 50)) +>T : Symbol(T, Decl(mappedTypes6.ts, 10, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 10, 27)) +>T : Symbol(T, Decl(mappedTypes6.ts, 10, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 10, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 10, 27)) + +type T09 = { +readonly [P in keyof T]?: T[P] }; +>T09 : Symbol(T09, Decl(mappedTypes6.ts, 10, 49)) +>T : Symbol(T, Decl(mappedTypes6.ts, 11, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 11, 27)) +>T : Symbol(T, Decl(mappedTypes6.ts, 11, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 11, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 11, 27)) + +type T10 = { +readonly [P in keyof T]+?: T[P] }; +>T10 : Symbol(T10, Decl(mappedTypes6.ts, 11, 50)) +>T : Symbol(T, Decl(mappedTypes6.ts, 12, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 12, 27)) +>T : Symbol(T, Decl(mappedTypes6.ts, 12, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 12, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 12, 27)) + +type T11 = { +readonly [P in keyof T]-?: T[P] }; +>T11 : Symbol(T11, Decl(mappedTypes6.ts, 12, 51)) +>T : Symbol(T, Decl(mappedTypes6.ts, 13, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 13, 27)) +>T : Symbol(T, Decl(mappedTypes6.ts, 13, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 13, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 13, 27)) + +type T12 = { -readonly [P in keyof T]: T[P] }; +>T12 : Symbol(T12, Decl(mappedTypes6.ts, 13, 51)) +>T : Symbol(T, Decl(mappedTypes6.ts, 15, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 15, 27)) +>T : Symbol(T, Decl(mappedTypes6.ts, 15, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 15, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 15, 27)) + +type T13 = { -readonly [P in keyof T]?: T[P] }; +>T13 : Symbol(T13, Decl(mappedTypes6.ts, 15, 49)) +>T : Symbol(T, Decl(mappedTypes6.ts, 16, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 16, 27)) +>T : Symbol(T, Decl(mappedTypes6.ts, 16, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 16, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 16, 27)) + +type T14 = { -readonly [P in keyof T]+?: T[P] }; +>T14 : Symbol(T14, Decl(mappedTypes6.ts, 16, 50)) +>T : Symbol(T, Decl(mappedTypes6.ts, 17, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 17, 27)) +>T : Symbol(T, Decl(mappedTypes6.ts, 17, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 17, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 17, 27)) + +type T15 = { -readonly [P in keyof T]-?: T[P] }; +>T15 : Symbol(T15, Decl(mappedTypes6.ts, 17, 51)) +>T : Symbol(T, Decl(mappedTypes6.ts, 18, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 18, 27)) +>T : Symbol(T, Decl(mappedTypes6.ts, 18, 9)) +>T : Symbol(T, Decl(mappedTypes6.ts, 18, 9)) +>P : Symbol(P, Decl(mappedTypes6.ts, 18, 27)) + +function f1(x: Required, y: T, z: Partial) { +>f1 : Symbol(f1, Decl(mappedTypes6.ts, 18, 51)) +>T : Symbol(T, Decl(mappedTypes6.ts, 20, 12)) +>x : Symbol(x, Decl(mappedTypes6.ts, 20, 15)) +>Required : Symbol(Required, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes6.ts, 20, 12)) +>y : Symbol(y, Decl(mappedTypes6.ts, 20, 30)) +>T : Symbol(T, Decl(mappedTypes6.ts, 20, 12)) +>z : Symbol(z, Decl(mappedTypes6.ts, 20, 36)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes6.ts, 20, 12)) + + x = x; +>x : Symbol(x, Decl(mappedTypes6.ts, 20, 15)) +>x : Symbol(x, Decl(mappedTypes6.ts, 20, 15)) + + x = y; // Error +>x : Symbol(x, Decl(mappedTypes6.ts, 20, 15)) +>y : Symbol(y, Decl(mappedTypes6.ts, 20, 30)) + + x = z; // Error +>x : Symbol(x, Decl(mappedTypes6.ts, 20, 15)) +>z : Symbol(z, Decl(mappedTypes6.ts, 20, 36)) + + y = x; +>y : Symbol(y, Decl(mappedTypes6.ts, 20, 30)) +>x : Symbol(x, Decl(mappedTypes6.ts, 20, 15)) + + y = y; +>y : Symbol(y, Decl(mappedTypes6.ts, 20, 30)) +>y : Symbol(y, Decl(mappedTypes6.ts, 20, 30)) + + y = z; // Error +>y : Symbol(y, Decl(mappedTypes6.ts, 20, 30)) +>z : Symbol(z, Decl(mappedTypes6.ts, 20, 36)) + + z = x; +>z : Symbol(z, Decl(mappedTypes6.ts, 20, 36)) +>x : Symbol(x, Decl(mappedTypes6.ts, 20, 15)) + + z = y; +>z : Symbol(z, Decl(mappedTypes6.ts, 20, 36)) +>y : Symbol(y, Decl(mappedTypes6.ts, 20, 30)) + + z = z; +>z : Symbol(z, Decl(mappedTypes6.ts, 20, 36)) +>z : Symbol(z, Decl(mappedTypes6.ts, 20, 36)) +} + +type Denullified = { [P in keyof T]-?: NonNullable }; +>Denullified : Symbol(Denullified, Decl(mappedTypes6.ts, 30, 1)) +>T : Symbol(T, Decl(mappedTypes6.ts, 32, 17)) +>P : Symbol(P, Decl(mappedTypes6.ts, 32, 25)) +>T : Symbol(T, Decl(mappedTypes6.ts, 32, 17)) +>NonNullable : Symbol(NonNullable, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes6.ts, 32, 17)) +>P : Symbol(P, Decl(mappedTypes6.ts, 32, 25)) + +function f2(w: Denullified, x: Required, y: T, z: Partial) { +>f2 : Symbol(f2, Decl(mappedTypes6.ts, 32, 62)) +>T : Symbol(T, Decl(mappedTypes6.ts, 34, 12)) +>w : Symbol(w, Decl(mappedTypes6.ts, 34, 15)) +>Denullified : Symbol(Denullified, Decl(mappedTypes6.ts, 30, 1)) +>T : Symbol(T, Decl(mappedTypes6.ts, 34, 12)) +>x : Symbol(x, Decl(mappedTypes6.ts, 34, 33)) +>Required : Symbol(Required, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes6.ts, 34, 12)) +>y : Symbol(y, Decl(mappedTypes6.ts, 34, 49)) +>T : Symbol(T, Decl(mappedTypes6.ts, 34, 12)) +>z : Symbol(z, Decl(mappedTypes6.ts, 34, 55)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes6.ts, 34, 12)) + + w = w; +>w : Symbol(w, Decl(mappedTypes6.ts, 34, 15)) +>w : Symbol(w, Decl(mappedTypes6.ts, 34, 15)) + + w = x; // Error +>w : Symbol(w, Decl(mappedTypes6.ts, 34, 15)) +>x : Symbol(x, Decl(mappedTypes6.ts, 34, 33)) + + w = y; // Error +>w : Symbol(w, Decl(mappedTypes6.ts, 34, 15)) +>y : Symbol(y, Decl(mappedTypes6.ts, 34, 49)) + + w = z; // Error +>w : Symbol(w, Decl(mappedTypes6.ts, 34, 15)) +>z : Symbol(z, Decl(mappedTypes6.ts, 34, 55)) + + x = w; +>x : Symbol(x, Decl(mappedTypes6.ts, 34, 33)) +>w : Symbol(w, Decl(mappedTypes6.ts, 34, 15)) + + x = x; +>x : Symbol(x, Decl(mappedTypes6.ts, 34, 33)) +>x : Symbol(x, Decl(mappedTypes6.ts, 34, 33)) + + x = y; // Error +>x : Symbol(x, Decl(mappedTypes6.ts, 34, 33)) +>y : Symbol(y, Decl(mappedTypes6.ts, 34, 49)) + + x = z; // Error +>x : Symbol(x, Decl(mappedTypes6.ts, 34, 33)) +>z : Symbol(z, Decl(mappedTypes6.ts, 34, 55)) + + y = w; +>y : Symbol(y, Decl(mappedTypes6.ts, 34, 49)) +>w : Symbol(w, Decl(mappedTypes6.ts, 34, 15)) + + y = x; +>y : Symbol(y, Decl(mappedTypes6.ts, 34, 49)) +>x : Symbol(x, Decl(mappedTypes6.ts, 34, 33)) + + y = y; +>y : Symbol(y, Decl(mappedTypes6.ts, 34, 49)) +>y : Symbol(y, Decl(mappedTypes6.ts, 34, 49)) + + y = z; // Error +>y : Symbol(y, Decl(mappedTypes6.ts, 34, 49)) +>z : Symbol(z, Decl(mappedTypes6.ts, 34, 55)) + + z = w; +>z : Symbol(z, Decl(mappedTypes6.ts, 34, 55)) +>w : Symbol(w, Decl(mappedTypes6.ts, 34, 15)) + + z = x; +>z : Symbol(z, Decl(mappedTypes6.ts, 34, 55)) +>x : Symbol(x, Decl(mappedTypes6.ts, 34, 33)) + + z = y; +>z : Symbol(z, Decl(mappedTypes6.ts, 34, 55)) +>y : Symbol(y, Decl(mappedTypes6.ts, 34, 49)) + + z = z; +>z : Symbol(z, Decl(mappedTypes6.ts, 34, 55)) +>z : Symbol(z, Decl(mappedTypes6.ts, 34, 55)) +} + + +function f3(w: Denullified, x: Required, y: T, z: Partial) { +>f3 : Symbol(f3, Decl(mappedTypes6.ts, 51, 1)) +>T : Symbol(T, Decl(mappedTypes6.ts, 54, 12)) +>w : Symbol(w, Decl(mappedTypes6.ts, 54, 15)) +>Denullified : Symbol(Denullified, Decl(mappedTypes6.ts, 30, 1)) +>T : Symbol(T, Decl(mappedTypes6.ts, 54, 12)) +>x : Symbol(x, Decl(mappedTypes6.ts, 54, 33)) +>Required : Symbol(Required, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes6.ts, 54, 12)) +>y : Symbol(y, Decl(mappedTypes6.ts, 54, 49)) +>T : Symbol(T, Decl(mappedTypes6.ts, 54, 12)) +>z : Symbol(z, Decl(mappedTypes6.ts, 54, 55)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes6.ts, 54, 12)) + + w = {}; // Error +>w : Symbol(w, Decl(mappedTypes6.ts, 54, 15)) + + x = {}; // Error +>x : Symbol(x, Decl(mappedTypes6.ts, 54, 33)) + + y = {}; // Error +>y : Symbol(y, Decl(mappedTypes6.ts, 54, 49)) + + z = {}; +>z : Symbol(z, Decl(mappedTypes6.ts, 54, 55)) +} + +type Readwrite = { +>Readwrite : Symbol(Readwrite, Decl(mappedTypes6.ts, 59, 1)) +>T : Symbol(T, Decl(mappedTypes6.ts, 61, 15)) + + -readonly [P in keyof T]: T[P]; +>P : Symbol(P, Decl(mappedTypes6.ts, 62, 15)) +>T : Symbol(T, Decl(mappedTypes6.ts, 61, 15)) +>T : Symbol(T, Decl(mappedTypes6.ts, 61, 15)) +>P : Symbol(P, Decl(mappedTypes6.ts, 62, 15)) +} + +function f10(x: Readonly, y: T, z: Readwrite) { +>f10 : Symbol(f10, Decl(mappedTypes6.ts, 63, 1)) +>T : Symbol(T, Decl(mappedTypes6.ts, 65, 13)) +>x : Symbol(x, Decl(mappedTypes6.ts, 65, 16)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T : Symbol(T, Decl(mappedTypes6.ts, 65, 13)) +>y : Symbol(y, Decl(mappedTypes6.ts, 65, 31)) +>T : Symbol(T, Decl(mappedTypes6.ts, 65, 13)) +>z : Symbol(z, Decl(mappedTypes6.ts, 65, 37)) +>Readwrite : Symbol(Readwrite, Decl(mappedTypes6.ts, 59, 1)) +>T : Symbol(T, Decl(mappedTypes6.ts, 65, 13)) + + x = x; +>x : Symbol(x, Decl(mappedTypes6.ts, 65, 16)) +>x : Symbol(x, Decl(mappedTypes6.ts, 65, 16)) + + x = y; +>x : Symbol(x, Decl(mappedTypes6.ts, 65, 16)) +>y : Symbol(y, Decl(mappedTypes6.ts, 65, 31)) + + x = z; +>x : Symbol(x, Decl(mappedTypes6.ts, 65, 16)) +>z : Symbol(z, Decl(mappedTypes6.ts, 65, 37)) + + y = x; +>y : Symbol(y, Decl(mappedTypes6.ts, 65, 31)) +>x : Symbol(x, Decl(mappedTypes6.ts, 65, 16)) + + y = y; +>y : Symbol(y, Decl(mappedTypes6.ts, 65, 31)) +>y : Symbol(y, Decl(mappedTypes6.ts, 65, 31)) + + y = z; +>y : Symbol(y, Decl(mappedTypes6.ts, 65, 31)) +>z : Symbol(z, Decl(mappedTypes6.ts, 65, 37)) + + z = x; +>z : Symbol(z, Decl(mappedTypes6.ts, 65, 37)) +>x : Symbol(x, Decl(mappedTypes6.ts, 65, 16)) + + z = y; +>z : Symbol(z, Decl(mappedTypes6.ts, 65, 37)) +>y : Symbol(y, Decl(mappedTypes6.ts, 65, 31)) + + z = z; +>z : Symbol(z, Decl(mappedTypes6.ts, 65, 37)) +>z : Symbol(z, Decl(mappedTypes6.ts, 65, 37)) +} + +type Foo = { +>Foo : Symbol(Foo, Decl(mappedTypes6.ts, 75, 1)) + + a: number; +>a : Symbol(a, Decl(mappedTypes6.ts, 77, 12)) + + b: number | undefined; +>b : Symbol(b, Decl(mappedTypes6.ts, 78, 14)) + + c?: number; +>c : Symbol(c, Decl(mappedTypes6.ts, 79, 26)) + + d?: number | undefined; +>d : Symbol(d, Decl(mappedTypes6.ts, 80, 15)) +} + +declare let x1: Foo; +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>Foo : Symbol(Foo, Decl(mappedTypes6.ts, 75, 1)) + +x1.a; // number +>x1.a : Symbol(a, Decl(mappedTypes6.ts, 77, 12)) +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 77, 12)) + +x1.b; // number | undefined +>x1.b : Symbol(b, Decl(mappedTypes6.ts, 78, 14)) +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>b : Symbol(b, Decl(mappedTypes6.ts, 78, 14)) + +x1.c; // number | undefined +>x1.c : Symbol(c, Decl(mappedTypes6.ts, 79, 26)) +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>c : Symbol(c, Decl(mappedTypes6.ts, 79, 26)) + +x1.d; // number | undefined +>x1.d : Symbol(d, Decl(mappedTypes6.ts, 80, 15)) +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>d : Symbol(d, Decl(mappedTypes6.ts, 80, 15)) + +x1 = { a: 1 }; // Error +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 91, 6)) + +x1 = { a: 1, b: 1 }; +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 92, 6)) +>b : Symbol(b, Decl(mappedTypes6.ts, 92, 12)) + +x1 = { a: 1, b: 1, c: 1 }; +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 93, 6)) +>b : Symbol(b, Decl(mappedTypes6.ts, 93, 12)) +>c : Symbol(c, Decl(mappedTypes6.ts, 93, 18)) + +x1 = { a: 1, b: 1, c: 1, d: 1 }; +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 94, 6)) +>b : Symbol(b, Decl(mappedTypes6.ts, 94, 12)) +>c : Symbol(c, Decl(mappedTypes6.ts, 94, 18)) +>d : Symbol(d, Decl(mappedTypes6.ts, 94, 24)) + +declare let x2: Required; +>x2 : Symbol(x2, Decl(mappedTypes6.ts, 96, 11)) +>Required : Symbol(Required, Decl(lib.d.ts, --, --)) +>Foo : Symbol(Foo, Decl(mappedTypes6.ts, 75, 1)) + +x1.a; // number +>x1.a : Symbol(a, Decl(mappedTypes6.ts, 77, 12)) +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 77, 12)) + +x1.b; // number | undefined +>x1.b : Symbol(b, Decl(mappedTypes6.ts, 78, 14)) +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>b : Symbol(b, Decl(mappedTypes6.ts, 78, 14)) + +x1.c; // number +>x1.c : Symbol(c, Decl(mappedTypes6.ts, 79, 26)) +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>c : Symbol(c, Decl(mappedTypes6.ts, 79, 26)) + +x1.d; // number +>x1.d : Symbol(d, Decl(mappedTypes6.ts, 80, 15)) +>x1 : Symbol(x1, Decl(mappedTypes6.ts, 84, 11)) +>d : Symbol(d, Decl(mappedTypes6.ts, 80, 15)) + +x2 = { a: 1 }; // Error +>x2 : Symbol(x2, Decl(mappedTypes6.ts, 96, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 103, 6)) + +x2 = { a: 1, b: 1 }; // Error +>x2 : Symbol(x2, Decl(mappedTypes6.ts, 96, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 104, 6)) +>b : Symbol(b, Decl(mappedTypes6.ts, 104, 12)) + +x2 = { a: 1, b: 1, c: 1 }; // Error +>x2 : Symbol(x2, Decl(mappedTypes6.ts, 96, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 105, 6)) +>b : Symbol(b, Decl(mappedTypes6.ts, 105, 12)) +>c : Symbol(c, Decl(mappedTypes6.ts, 105, 18)) + +x2 = { a: 1, b: 1, c: 1, d: 1 }; +>x2 : Symbol(x2, Decl(mappedTypes6.ts, 96, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 106, 6)) +>b : Symbol(b, Decl(mappedTypes6.ts, 106, 12)) +>c : Symbol(c, Decl(mappedTypes6.ts, 106, 18)) +>d : Symbol(d, Decl(mappedTypes6.ts, 106, 24)) + +type Bar = { +>Bar : Symbol(Bar, Decl(mappedTypes6.ts, 106, 32)) + + a: number; +>a : Symbol(a, Decl(mappedTypes6.ts, 108, 12)) + + readonly b: number; +>b : Symbol(b, Decl(mappedTypes6.ts, 109, 14)) +} + +declare let x3: Bar; +>x3 : Symbol(x3, Decl(mappedTypes6.ts, 113, 11)) +>Bar : Symbol(Bar, Decl(mappedTypes6.ts, 106, 32)) + +x3.a = 1; +>x3.a : Symbol(a, Decl(mappedTypes6.ts, 108, 12)) +>x3 : Symbol(x3, Decl(mappedTypes6.ts, 113, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 108, 12)) + +x3.b = 1; // Error +>x3.b : Symbol(b, Decl(mappedTypes6.ts, 109, 14)) +>x3 : Symbol(x3, Decl(mappedTypes6.ts, 113, 11)) +>b : Symbol(b, Decl(mappedTypes6.ts, 109, 14)) + +declare let x4: Readonly; +>x4 : Symbol(x4, Decl(mappedTypes6.ts, 117, 11)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>Bar : Symbol(Bar, Decl(mappedTypes6.ts, 106, 32)) + +x4.a = 1; // Error +>x4.a : Symbol(a, Decl(mappedTypes6.ts, 108, 12)) +>x4 : Symbol(x4, Decl(mappedTypes6.ts, 117, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 108, 12)) + +x4.b = 1; // Error +>x4.b : Symbol(b, Decl(mappedTypes6.ts, 109, 14)) +>x4 : Symbol(x4, Decl(mappedTypes6.ts, 117, 11)) +>b : Symbol(b, Decl(mappedTypes6.ts, 109, 14)) + +declare let x5: Readwrite; +>x5 : Symbol(x5, Decl(mappedTypes6.ts, 121, 11)) +>Readwrite : Symbol(Readwrite, Decl(mappedTypes6.ts, 59, 1)) +>Bar : Symbol(Bar, Decl(mappedTypes6.ts, 106, 32)) + +x5.a = 1; +>x5.a : Symbol(a, Decl(mappedTypes6.ts, 108, 12)) +>x5 : Symbol(x5, Decl(mappedTypes6.ts, 121, 11)) +>a : Symbol(a, Decl(mappedTypes6.ts, 108, 12)) + +x5.b = 1; +>x5.b : Symbol(b, Decl(mappedTypes6.ts, 109, 14)) +>x5 : Symbol(x5, Decl(mappedTypes6.ts, 121, 11)) +>b : Symbol(b, Decl(mappedTypes6.ts, 109, 14)) + diff --git a/tests/baselines/reference/mappedTypes6.types b/tests/baselines/reference/mappedTypes6.types new file mode 100644 index 0000000000000..5b554d53fe724 --- /dev/null +++ b/tests/baselines/reference/mappedTypes6.types @@ -0,0 +1,609 @@ +=== tests/cases/conformance/types/mapped/mappedTypes6.ts === +type T00 = { [P in keyof T]: T[P] }; +>T00 : T00 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T01 = { [P in keyof T]?: T[P] }; +>T01 : T01 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T02 = { [P in keyof T]+?: T[P] }; +>T02 : T02 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T03 = { [P in keyof T]-?: T[P] }; +>T03 : T03 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T04 = { readonly [P in keyof T]: T[P] }; +>T04 : T04 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T05 = { readonly [P in keyof T]?: T[P] }; +>T05 : T05 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T06 = { readonly [P in keyof T]+?: T[P] }; +>T06 : T06 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T07 = { readonly [P in keyof T]-?: T[P] }; +>T07 : T07 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T08 = { +readonly [P in keyof T]: T[P] }; +>T08 : T08 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T09 = { +readonly [P in keyof T]?: T[P] }; +>T09 : T09 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T10 = { +readonly [P in keyof T]+?: T[P] }; +>T10 : T10 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T11 = { +readonly [P in keyof T]-?: T[P] }; +>T11 : T11 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T12 = { -readonly [P in keyof T]: T[P] }; +>T12 : T12 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T13 = { -readonly [P in keyof T]?: T[P] }; +>T13 : T13 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T14 = { -readonly [P in keyof T]+?: T[P] }; +>T14 : T14 +>T : T +>P : P +>T : T +>T : T +>P : P + +type T15 = { -readonly [P in keyof T]-?: T[P] }; +>T15 : T15 +>T : T +>P : P +>T : T +>T : T +>P : P + +function f1(x: Required, y: T, z: Partial) { +>f1 : (x: Required, y: T, z: Partial) => void +>T : T +>x : Required +>Required : Required +>T : T +>y : T +>T : T +>z : Partial +>Partial : Partial +>T : T + + x = x; +>x = x : Required +>x : Required +>x : Required + + x = y; // Error +>x = y : T +>x : Required +>y : T + + x = z; // Error +>x = z : Partial +>x : Required +>z : Partial + + y = x; +>y = x : Required +>y : T +>x : Required + + y = y; +>y = y : T +>y : T +>y : T + + y = z; // Error +>y = z : Partial +>y : T +>z : Partial + + z = x; +>z = x : Required +>z : Partial +>x : Required + + z = y; +>z = y : T +>z : Partial +>y : T + + z = z; +>z = z : Partial +>z : Partial +>z : Partial +} + +type Denullified = { [P in keyof T]-?: NonNullable }; +>Denullified : Denullified +>T : T +>P : P +>T : T +>NonNullable : NonNullable +>T : T +>P : P + +function f2(w: Denullified, x: Required, y: T, z: Partial) { +>f2 : (w: Denullified, x: Required, y: T, z: Partial) => void +>T : T +>w : Denullified +>Denullified : Denullified +>T : T +>x : Required +>Required : Required +>T : T +>y : T +>T : T +>z : Partial +>Partial : Partial +>T : T + + w = w; +>w = w : Denullified +>w : Denullified +>w : Denullified + + w = x; // Error +>w = x : Required +>w : Denullified +>x : Required + + w = y; // Error +>w = y : T +>w : Denullified +>y : T + + w = z; // Error +>w = z : Partial +>w : Denullified +>z : Partial + + x = w; +>x = w : Denullified +>x : Required +>w : Denullified + + x = x; +>x = x : Required +>x : Required +>x : Required + + x = y; // Error +>x = y : T +>x : Required +>y : T + + x = z; // Error +>x = z : Partial +>x : Required +>z : Partial + + y = w; +>y = w : Denullified +>y : T +>w : Denullified + + y = x; +>y = x : Required +>y : T +>x : Required + + y = y; +>y = y : T +>y : T +>y : T + + y = z; // Error +>y = z : Partial +>y : T +>z : Partial + + z = w; +>z = w : Denullified +>z : Partial +>w : Denullified + + z = x; +>z = x : Required +>z : Partial +>x : Required + + z = y; +>z = y : T +>z : Partial +>y : T + + z = z; +>z = z : Partial +>z : Partial +>z : Partial +} + + +function f3(w: Denullified, x: Required, y: T, z: Partial) { +>f3 : (w: Denullified, x: Required, y: T, z: Partial) => void +>T : T +>w : Denullified +>Denullified : Denullified +>T : T +>x : Required +>Required : Required +>T : T +>y : T +>T : T +>z : Partial +>Partial : Partial +>T : T + + w = {}; // Error +>w = {} : {} +>w : Denullified +>{} : {} + + x = {}; // Error +>x = {} : {} +>x : Required +>{} : {} + + y = {}; // Error +>y = {} : {} +>y : T +>{} : {} + + z = {}; +>z = {} : {} +>z : Partial +>{} : {} +} + +type Readwrite = { +>Readwrite : Readwrite +>T : T + + -readonly [P in keyof T]: T[P]; +>P : P +>T : T +>T : T +>P : P +} + +function f10(x: Readonly, y: T, z: Readwrite) { +>f10 : (x: Readonly, y: T, z: Readwrite) => void +>T : T +>x : Readonly +>Readonly : Readonly +>T : T +>y : T +>T : T +>z : Readwrite +>Readwrite : Readwrite +>T : T + + x = x; +>x = x : Readonly +>x : Readonly +>x : Readonly + + x = y; +>x = y : T +>x : Readonly +>y : T + + x = z; +>x = z : Readwrite +>x : Readonly +>z : Readwrite + + y = x; +>y = x : Readonly +>y : T +>x : Readonly + + y = y; +>y = y : T +>y : T +>y : T + + y = z; +>y = z : Readwrite +>y : T +>z : Readwrite + + z = x; +>z = x : Readonly +>z : Readwrite +>x : Readonly + + z = y; +>z = y : T +>z : Readwrite +>y : T + + z = z; +>z = z : Readwrite +>z : Readwrite +>z : Readwrite +} + +type Foo = { +>Foo : Foo + + a: number; +>a : number + + b: number | undefined; +>b : number | undefined + + c?: number; +>c : number | undefined + + d?: number | undefined; +>d : number | undefined +} + +declare let x1: Foo; +>x1 : Foo +>Foo : Foo + +x1.a; // number +>x1.a : number +>x1 : Foo +>a : number + +x1.b; // number | undefined +>x1.b : number | undefined +>x1 : Foo +>b : number | undefined + +x1.c; // number | undefined +>x1.c : number | undefined +>x1 : Foo +>c : number | undefined + +x1.d; // number | undefined +>x1.d : number | undefined +>x1 : Foo +>d : number | undefined + +x1 = { a: 1 }; // Error +>x1 = { a: 1 } : { a: number; } +>x1 : Foo +>{ a: 1 } : { a: number; } +>a : number +>1 : 1 + +x1 = { a: 1, b: 1 }; +>x1 = { a: 1, b: 1 } : { a: number; b: number; } +>x1 : Foo +>{ a: 1, b: 1 } : { a: number; b: number; } +>a : number +>1 : 1 +>b : number +>1 : 1 + +x1 = { a: 1, b: 1, c: 1 }; +>x1 = { a: 1, b: 1, c: 1 } : { a: number; b: number; c: number; } +>x1 : Foo +>{ a: 1, b: 1, c: 1 } : { a: number; b: number; c: number; } +>a : number +>1 : 1 +>b : number +>1 : 1 +>c : number +>1 : 1 + +x1 = { a: 1, b: 1, c: 1, d: 1 }; +>x1 = { a: 1, b: 1, c: 1, d: 1 } : { a: number; b: number; c: number; d: number; } +>x1 : Foo +>{ a: 1, b: 1, c: 1, d: 1 } : { a: number; b: number; c: number; d: number; } +>a : number +>1 : 1 +>b : number +>1 : 1 +>c : number +>1 : 1 +>d : number +>1 : 1 + +declare let x2: Required; +>x2 : Required +>Required : Required +>Foo : Foo + +x1.a; // number +>x1.a : number +>x1 : Foo +>a : number + +x1.b; // number | undefined +>x1.b : number | undefined +>x1 : Foo +>b : number | undefined + +x1.c; // number +>x1.c : number | undefined +>x1 : Foo +>c : number | undefined + +x1.d; // number +>x1.d : number | undefined +>x1 : Foo +>d : number | undefined + +x2 = { a: 1 }; // Error +>x2 = { a: 1 } : { a: number; } +>x2 : Required +>{ a: 1 } : { a: number; } +>a : number +>1 : 1 + +x2 = { a: 1, b: 1 }; // Error +>x2 = { a: 1, b: 1 } : { a: number; b: number; } +>x2 : Required +>{ a: 1, b: 1 } : { a: number; b: number; } +>a : number +>1 : 1 +>b : number +>1 : 1 + +x2 = { a: 1, b: 1, c: 1 }; // Error +>x2 = { a: 1, b: 1, c: 1 } : { a: number; b: number; c: number; } +>x2 : Required +>{ a: 1, b: 1, c: 1 } : { a: number; b: number; c: number; } +>a : number +>1 : 1 +>b : number +>1 : 1 +>c : number +>1 : 1 + +x2 = { a: 1, b: 1, c: 1, d: 1 }; +>x2 = { a: 1, b: 1, c: 1, d: 1 } : { a: number; b: number; c: number; d: number; } +>x2 : Required +>{ a: 1, b: 1, c: 1, d: 1 } : { a: number; b: number; c: number; d: number; } +>a : number +>1 : 1 +>b : number +>1 : 1 +>c : number +>1 : 1 +>d : number +>1 : 1 + +type Bar = { +>Bar : Bar + + a: number; +>a : number + + readonly b: number; +>b : number +} + +declare let x3: Bar; +>x3 : Bar +>Bar : Bar + +x3.a = 1; +>x3.a = 1 : 1 +>x3.a : number +>x3 : Bar +>a : number +>1 : 1 + +x3.b = 1; // Error +>x3.b = 1 : 1 +>x3.b : any +>x3 : Bar +>b : any +>1 : 1 + +declare let x4: Readonly; +>x4 : Readonly +>Readonly : Readonly +>Bar : Bar + +x4.a = 1; // Error +>x4.a = 1 : 1 +>x4.a : any +>x4 : Readonly +>a : any +>1 : 1 + +x4.b = 1; // Error +>x4.b = 1 : 1 +>x4.b : any +>x4 : Readonly +>b : any +>1 : 1 + +declare let x5: Readwrite; +>x5 : Readwrite +>Readwrite : Readwrite +>Bar : Bar + +x5.a = 1; +>x5.a = 1 : 1 +>x5.a : number +>x5 : Readwrite +>a : number +>1 : 1 + +x5.b = 1; +>x5.b = 1 : 1 +>x5.b : number +>x5 : Readwrite +>b : number +>1 : 1 + diff --git a/tests/cases/conformance/types/mapped/mappedTypes6.ts b/tests/cases/conformance/types/mapped/mappedTypes6.ts new file mode 100644 index 0000000000000..b3beef768466f --- /dev/null +++ b/tests/cases/conformance/types/mapped/mappedTypes6.ts @@ -0,0 +1,127 @@ +// @strict: true +// @declaration: true + +type T00 = { [P in keyof T]: T[P] }; +type T01 = { [P in keyof T]?: T[P] }; +type T02 = { [P in keyof T]+?: T[P] }; +type T03 = { [P in keyof T]-?: T[P] }; + +type T04 = { readonly [P in keyof T]: T[P] }; +type T05 = { readonly [P in keyof T]?: T[P] }; +type T06 = { readonly [P in keyof T]+?: T[P] }; +type T07 = { readonly [P in keyof T]-?: T[P] }; + +type T08 = { +readonly [P in keyof T]: T[P] }; +type T09 = { +readonly [P in keyof T]?: T[P] }; +type T10 = { +readonly [P in keyof T]+?: T[P] }; +type T11 = { +readonly [P in keyof T]-?: T[P] }; + +type T12 = { -readonly [P in keyof T]: T[P] }; +type T13 = { -readonly [P in keyof T]?: T[P] }; +type T14 = { -readonly [P in keyof T]+?: T[P] }; +type T15 = { -readonly [P in keyof T]-?: T[P] }; + +function f1(x: Required, y: T, z: Partial) { + x = x; + x = y; // Error + x = z; // Error + y = x; + y = y; + y = z; // Error + z = x; + z = y; + z = z; +} + +type Denullified = { [P in keyof T]-?: NonNullable }; + +function f2(w: Denullified, x: Required, y: T, z: Partial) { + w = w; + w = x; // Error + w = y; // Error + w = z; // Error + x = w; + x = x; + x = y; // Error + x = z; // Error + y = w; + y = x; + y = y; + y = z; // Error + z = w; + z = x; + z = y; + z = z; +} + + +function f3(w: Denullified, x: Required, y: T, z: Partial) { + w = {}; // Error + x = {}; // Error + y = {}; // Error + z = {}; +} + +type Readwrite = { + -readonly [P in keyof T]: T[P]; +} + +function f10(x: Readonly, y: T, z: Readwrite) { + x = x; + x = y; + x = z; + y = x; + y = y; + y = z; + z = x; + z = y; + z = z; +} + +type Foo = { + a: number; + b: number | undefined; + c?: number; + d?: number | undefined; +} + +declare let x1: Foo; + +x1.a; // number +x1.b; // number | undefined +x1.c; // number | undefined +x1.d; // number | undefined + +x1 = { a: 1 }; // Error +x1 = { a: 1, b: 1 }; +x1 = { a: 1, b: 1, c: 1 }; +x1 = { a: 1, b: 1, c: 1, d: 1 }; + +declare let x2: Required; + +x1.a; // number +x1.b; // number | undefined +x1.c; // number +x1.d; // number + +x2 = { a: 1 }; // Error +x2 = { a: 1, b: 1 }; // Error +x2 = { a: 1, b: 1, c: 1 }; // Error +x2 = { a: 1, b: 1, c: 1, d: 1 }; + +type Bar = { + a: number; + readonly b: number; +} + +declare let x3: Bar; +x3.a = 1; +x3.b = 1; // Error + +declare let x4: Readonly; +x4.a = 1; // Error +x4.b = 1; // Error + +declare let x5: Readwrite; +x5.a = 1; +x5.b = 1;