Merge pull request #21919 from Microsoft/mappedTypeModifiers

Improved control over mapped type modifiers
This commit is contained in:
Anders Hejlsberg
2018-02-13 11:21:07 -08:00
committed by GitHub
14 changed files with 1828 additions and 54 deletions
+41 -25
View File
@@ -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 ? <ReadonlyToken | PlusToken | MinusToken>createToken(type.declaration.readonlyToken.kind) : undefined;
const questionToken = type.declaration.questionToken ? <QuestionToken | PlusToken | MinusToken>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(<MappedType>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 &&
(<TypeOperatorNode>constraintDeclaration).operator === SyntaxKind.KeyOfKeyword) {
@@ -5888,10 +5889,17 @@ namespace ts {
if (t.flags & TypeFlags.StringLiteral) {
const propName = escapeLeadingUnderscores((<StringLiteralType>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 getCombinedMappedTypeModifiers(type: MappedType): MappedTypeModifiers {
function getMappedTypeOptionality(type: MappedType): number {
const modifiers = getMappedTypeModifiers(type);
return modifiers & MappedTypeModifiers.ExcludeOptional ? -1 : modifiers & MappedTypeModifiers.IncludeOptional ? 1 : 0;
}
function getCombinedMappedTypeOptionality(type: MappedType): number {
const optionality = getMappedTypeOptionality(type);
const modifiersType = getModifiersTypeFromMappedType(type);
return getMappedTypeModifiers(type) |
(isGenericMappedType(modifiersType) ? getMappedTypeModifiers(<MappedType>modifiersType) : 0);
return optionality || (isGenericMappedType(modifiersType) ? getMappedTypeOptionality(<MappedType>modifiersType) : 0);
}
function isPartialMappedType(type: Type) {
return getObjectFlags(type) & ObjectFlags.Mapped && !!(<MappedType>type).declaration.questionToken;
return !!(getObjectFlags(type) & ObjectFlags.Mapped && getMappedTypeModifiers(<MappedType>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(<MappedType>source) === getIndexType(target)) {
if (!(<MappedType>source).declaration.questionToken) {
if (!(getMappedTypeModifiers(<MappedType>source) & MappedTypeModifiers.IncludeOptional)) {
const templateType = getTemplateTypeFromMappedType(<MappedType>source);
const indexedAccessType = getIndexedAccessType(target, getTypeParameterFromMappedType(<MappedType>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(<MappedType>target);
const modifiers = getMappedTypeModifiers(<MappedType>target);
if (!(modifiers & MappedTypeModifiers.ExcludeOptional)) {
if (template.flags & TypeFlags.IndexedAccess && (<IndexedAccessType>template).objectType === source &&
(<IndexedAccessType>template).indexType === getTypeParameterFromMappedType(<MappedType>target)) {
return Ternary.True;
@@ -10013,6 +10029,7 @@ namespace ts {
}
}
}
}
if (source.flags & TypeFlags.TypeParameter) {
let constraint = getConstraintForRelation(<TypeParameter>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(<MappedType>target), getConstraintTypeFromMappedType(<MappedType>source), reportErrors)) {
@@ -20345,7 +20361,7 @@ namespace ts {
const indexType = (<IndexedAccessType>type).indexType;
if (isTypeAssignableTo(indexType, getIndexType(objectType))) {
if (accessNode.kind === SyntaxKind.ElementAccessExpression && isAssignmentTarget(accessNode) &&
getObjectFlags(objectType) & ObjectFlags.Mapped && (<MappedType>objectType).declaration.readonlyToken) {
getObjectFlags(objectType) & ObjectFlags.Mapped && getMappedTypeModifiers(<MappedType>objectType) & MappedTypeModifiers.IncludeReadonly) {
error(accessNode, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
}
return type;
+6 -2
View File
@@ -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);
+9 -3
View File
@@ -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);
+2 -2
View File
@@ -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
+24 -12
View File
@@ -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<TKind extends SyntaxKind>(t: TKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Token<TKind>;
function parseExpectedToken(t: SyntaxKind, reportAtCurrentPosition: boolean, diagnosticMessage: DiagnosticMessage, arg0?: any): Node {
function parseExpectedToken<TKind extends SyntaxKind>(t: TKind, diagnosticMessage?: DiagnosticMessage, arg0?: any): Token<TKind>;
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 extends Node>(): T {
@@ -2113,7 +2113,7 @@ namespace ts {
literal = parseTemplateMiddleOrTemplateTail();
}
else {
literal = <TemplateTail>parseExpectedToken(SyntaxKind.TemplateTail, /*reportAtCurrentPosition*/ false, Diagnostics._0_expected, tokenToString(SyntaxKind.CloseBraceToken));
literal = <TemplateTail>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 = <MappedTypeNode>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<ParameterDeclaration>([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 = <PropertyAccessExpression>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);
}
+4 -2
View File
@@ -661,6 +661,8 @@ namespace ts {
export type AtToken = Token<SyntaxKind.AtToken>;
export type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
export type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
export type PlusToken = Token<SyntaxKind.PlusToken>;
export type MinusToken = Token<SyntaxKind.MinusToken>;
export type Modifier
= Token<SyntaxKind.AbstractKeyword>
@@ -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;
}
+7
View File
@@ -1317,6 +1317,13 @@ type Partial<T> = {
[P in keyof T]?: T[P];
};
/**
* Make all properties in T required
*/
type Required<T> = {
[P in keyof T]-?: T[P];
};
/**
* Make all properties in T readonly
*/
+6 -4
View File
@@ -477,6 +477,8 @@ declare namespace ts {
type AtToken = Token<SyntaxKind.AtToken>;
type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
type PlusToken = Token<SyntaxKind.PlusToken>;
type MinusToken = Token<SyntaxKind.MinusToken>;
type Modifier = Token<SyntaxKind.AbstractKeyword> | Token<SyntaxKind.AsyncKeyword> | Token<SyntaxKind.ConstKeyword> | Token<SyntaxKind.DeclareKeyword> | Token<SyntaxKind.DefaultKeyword> | Token<SyntaxKind.ExportKeyword> | Token<SyntaxKind.PublicKeyword> | Token<SyntaxKind.PrivateKeyword> | Token<SyntaxKind.ProtectedKeyword> | Token<SyntaxKind.ReadonlyKeyword> | Token<SyntaxKind.StaticKeyword>;
type ModifiersArray = NodeArray<Modifier>;
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<BindingElement>): ObjectBindingPattern;
+6 -4
View File
@@ -477,6 +477,8 @@ declare namespace ts {
type AtToken = Token<SyntaxKind.AtToken>;
type ReadonlyToken = Token<SyntaxKind.ReadonlyKeyword>;
type AwaitKeywordToken = Token<SyntaxKind.AwaitKeyword>;
type PlusToken = Token<SyntaxKind.PlusToken>;
type MinusToken = Token<SyntaxKind.MinusToken>;
type Modifier = Token<SyntaxKind.AbstractKeyword> | Token<SyntaxKind.AsyncKeyword> | Token<SyntaxKind.ConstKeyword> | Token<SyntaxKind.DeclareKeyword> | Token<SyntaxKind.DefaultKeyword> | Token<SyntaxKind.ExportKeyword> | Token<SyntaxKind.PublicKeyword> | Token<SyntaxKind.PrivateKeyword> | Token<SyntaxKind.ProtectedKeyword> | Token<SyntaxKind.ReadonlyKeyword> | Token<SyntaxKind.StaticKeyword>;
type ModifiersArray = NodeArray<Modifier>;
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<BindingElement>): ObjectBindingPattern;
@@ -0,0 +1,195 @@
tests/cases/conformance/types/mapped/mappedTypes6.ts(23,5): error TS2322: Type 'T' is not assignable to type 'Required<T>'.
tests/cases/conformance/types/mapped/mappedTypes6.ts(24,5): error TS2322: Type 'Partial<T>' is not assignable to type 'Required<T>'.
tests/cases/conformance/types/mapped/mappedTypes6.ts(27,5): error TS2322: Type 'Partial<T>' is not assignable to type 'T'.
tests/cases/conformance/types/mapped/mappedTypes6.ts(37,5): error TS2322: Type 'Required<T>' is not assignable to type 'Denullified<T>'.
Type 'T[P]' is not assignable to type 'NonNullable<T[P]>'.
tests/cases/conformance/types/mapped/mappedTypes6.ts(38,5): error TS2322: Type 'T' is not assignable to type 'Denullified<T>'.
tests/cases/conformance/types/mapped/mappedTypes6.ts(39,5): error TS2322: Type 'Partial<T>' is not assignable to type 'Denullified<T>'.
tests/cases/conformance/types/mapped/mappedTypes6.ts(42,5): error TS2322: Type 'T' is not assignable to type 'Required<T>'.
tests/cases/conformance/types/mapped/mappedTypes6.ts(43,5): error TS2322: Type 'Partial<T>' is not assignable to type 'Required<T>'.
tests/cases/conformance/types/mapped/mappedTypes6.ts(47,5): error TS2322: Type 'Partial<T>' is not assignable to type 'T'.
tests/cases/conformance/types/mapped/mappedTypes6.ts(56,5): error TS2322: Type '{}' is not assignable to type 'Denullified<T>'.
tests/cases/conformance/types/mapped/mappedTypes6.ts(57,5): error TS2322: Type '{}' is not assignable to type 'Required<T>'.
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<Foo>'.
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<Foo>'.
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<Foo>'.
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<T> = { [P in keyof T]: T[P] };
type T01<T> = { [P in keyof T]?: T[P] };
type T02<T> = { [P in keyof T]+?: T[P] };
type T03<T> = { [P in keyof T]-?: T[P] };
type T04<T> = { readonly [P in keyof T]: T[P] };
type T05<T> = { readonly [P in keyof T]?: T[P] };
type T06<T> = { readonly [P in keyof T]+?: T[P] };
type T07<T> = { readonly [P in keyof T]-?: T[P] };
type T08<T> = { +readonly [P in keyof T]: T[P] };
type T09<T> = { +readonly [P in keyof T]?: T[P] };
type T10<T> = { +readonly [P in keyof T]+?: T[P] };
type T11<T> = { +readonly [P in keyof T]-?: T[P] };
type T12<T> = { -readonly [P in keyof T]: T[P] };
type T13<T> = { -readonly [P in keyof T]?: T[P] };
type T14<T> = { -readonly [P in keyof T]+?: T[P] };
type T15<T> = { -readonly [P in keyof T]-?: T[P] };
function f1<T>(x: Required<T>, y: T, z: Partial<T>) {
x = x;
x = y; // Error
~
!!! error TS2322: Type 'T' is not assignable to type 'Required<T>'.
x = z; // Error
~
!!! error TS2322: Type 'Partial<T>' is not assignable to type 'Required<T>'.
y = x;
y = y;
y = z; // Error
~
!!! error TS2322: Type 'Partial<T>' is not assignable to type 'T'.
z = x;
z = y;
z = z;
}
type Denullified<T> = { [P in keyof T]-?: NonNullable<T[P]> };
function f2<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) {
w = w;
w = x; // Error
~
!!! error TS2322: Type 'Required<T>' is not assignable to type 'Denullified<T>'.
!!! error TS2322: Type 'T[P]' is not assignable to type 'NonNullable<T[P]>'.
w = y; // Error
~
!!! error TS2322: Type 'T' is not assignable to type 'Denullified<T>'.
w = z; // Error
~
!!! error TS2322: Type 'Partial<T>' is not assignable to type 'Denullified<T>'.
x = w;
x = x;
x = y; // Error
~
!!! error TS2322: Type 'T' is not assignable to type 'Required<T>'.
x = z; // Error
~
!!! error TS2322: Type 'Partial<T>' is not assignable to type 'Required<T>'.
y = w;
y = x;
y = y;
y = z; // Error
~
!!! error TS2322: Type 'Partial<T>' is not assignable to type 'T'.
z = w;
z = x;
z = y;
z = z;
}
function f3<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) {
w = {}; // Error
~
!!! error TS2322: Type '{}' is not assignable to type 'Denullified<T>'.
x = {}; // Error
~
!!! error TS2322: Type '{}' is not assignable to type 'Required<T>'.
y = {}; // Error
~
!!! error TS2322: Type '{}' is not assignable to type 'T'.
z = {};
}
type Readwrite<T> = {
-readonly [P in keyof T]: T[P];
}
function f10<T>(x: Readonly<T>, y: T, z: Readwrite<T>) {
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<Foo>;
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<Foo>'.
!!! 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<Foo>'.
!!! 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<Foo>'.
!!! 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<Bar>;
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<Bar>;
x5.a = 1;
x5.b = 1;
+273
View File
@@ -0,0 +1,273 @@
//// [mappedTypes6.ts]
type T00<T> = { [P in keyof T]: T[P] };
type T01<T> = { [P in keyof T]?: T[P] };
type T02<T> = { [P in keyof T]+?: T[P] };
type T03<T> = { [P in keyof T]-?: T[P] };
type T04<T> = { readonly [P in keyof T]: T[P] };
type T05<T> = { readonly [P in keyof T]?: T[P] };
type T06<T> = { readonly [P in keyof T]+?: T[P] };
type T07<T> = { readonly [P in keyof T]-?: T[P] };
type T08<T> = { +readonly [P in keyof T]: T[P] };
type T09<T> = { +readonly [P in keyof T]?: T[P] };
type T10<T> = { +readonly [P in keyof T]+?: T[P] };
type T11<T> = { +readonly [P in keyof T]-?: T[P] };
type T12<T> = { -readonly [P in keyof T]: T[P] };
type T13<T> = { -readonly [P in keyof T]?: T[P] };
type T14<T> = { -readonly [P in keyof T]+?: T[P] };
type T15<T> = { -readonly [P in keyof T]-?: T[P] };
function f1<T>(x: Required<T>, y: T, z: Partial<T>) {
x = x;
x = y; // Error
x = z; // Error
y = x;
y = y;
y = z; // Error
z = x;
z = y;
z = z;
}
type Denullified<T> = { [P in keyof T]-?: NonNullable<T[P]> };
function f2<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) {
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<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) {
w = {}; // Error
x = {}; // Error
y = {}; // Error
z = {};
}
type Readwrite<T> = {
-readonly [P in keyof T]: T[P];
}
function f10<T>(x: Readonly<T>, y: T, z: Readwrite<T>) {
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<Foo>;
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<Bar>;
x4.a = 1; // Error
x4.b = 1; // Error
declare let x5: Readwrite<Bar>;
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<T> = {
[P in keyof T]: T[P];
};
declare type T01<T> = {
[P in keyof T]?: T[P];
};
declare type T02<T> = {
[P in keyof T]+?: T[P];
};
declare type T03<T> = {
[P in keyof T]-?: T[P];
};
declare type T04<T> = {
readonly [P in keyof T]: T[P];
};
declare type T05<T> = {
readonly [P in keyof T]?: T[P];
};
declare type T06<T> = {
readonly [P in keyof T]+?: T[P];
};
declare type T07<T> = {
readonly [P in keyof T]-?: T[P];
};
declare type T08<T> = {
+readonly [P in keyof T]: T[P];
};
declare type T09<T> = {
+readonly [P in keyof T]?: T[P];
};
declare type T10<T> = {
+readonly [P in keyof T]+?: T[P];
};
declare type T11<T> = {
+readonly [P in keyof T]-?: T[P];
};
declare type T12<T> = {
-readonly [P in keyof T]: T[P];
};
declare type T13<T> = {
-readonly [P in keyof T]?: T[P];
};
declare type T14<T> = {
-readonly [P in keyof T]+?: T[P];
};
declare type T15<T> = {
-readonly [P in keyof T]-?: T[P];
};
declare function f1<T>(x: Required<T>, y: T, z: Partial<T>): void;
declare type Denullified<T> = {
[P in keyof T]-?: NonNullable<T[P]>;
};
declare function f2<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>): void;
declare function f3<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>): void;
declare type Readwrite<T> = {
-readonly [P in keyof T]: T[P];
};
declare function f10<T>(x: Readonly<T>, y: T, z: Readwrite<T>): void;
declare type Foo = {
a: number;
b: number | undefined;
c?: number;
d?: number | undefined;
};
declare let x1: Foo;
declare let x2: Required<Foo>;
declare type Bar = {
a: number;
readonly b: number;
};
declare let x3: Bar;
declare let x4: Readonly<Bar>;
declare let x5: Readwrite<Bar>;
@@ -0,0 +1,519 @@
=== tests/cases/conformance/types/mapped/mappedTypes6.ts ===
type T00<T> = { [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<T> = { [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<T> = { [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<T> = { [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<T> = { 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<T> = { 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<T> = { 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<T> = { 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<T> = { +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<T> = { +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<T> = { +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<T> = { +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<T> = { -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<T> = { -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<T> = { -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<T> = { -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<T>(x: Required<T>, y: T, z: Partial<T>) {
>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<T> = { [P in keyof T]-?: NonNullable<T[P]> };
>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<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) {
>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<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) {
>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<T> = {
>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<T>(x: Readonly<T>, y: T, z: Readwrite<T>) {
>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<Foo>;
>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<Bar>;
>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<Bar>;
>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))
@@ -0,0 +1,609 @@
=== tests/cases/conformance/types/mapped/mappedTypes6.ts ===
type T00<T> = { [P in keyof T]: T[P] };
>T00 : T00<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T01<T> = { [P in keyof T]?: T[P] };
>T01 : T01<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T02<T> = { [P in keyof T]+?: T[P] };
>T02 : T02<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T03<T> = { [P in keyof T]-?: T[P] };
>T03 : T03<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T04<T> = { readonly [P in keyof T]: T[P] };
>T04 : T04<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T05<T> = { readonly [P in keyof T]?: T[P] };
>T05 : T05<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T06<T> = { readonly [P in keyof T]+?: T[P] };
>T06 : T06<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T07<T> = { readonly [P in keyof T]-?: T[P] };
>T07 : T07<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T08<T> = { +readonly [P in keyof T]: T[P] };
>T08 : T08<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T09<T> = { +readonly [P in keyof T]?: T[P] };
>T09 : T09<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T10<T> = { +readonly [P in keyof T]+?: T[P] };
>T10 : T10<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T11<T> = { +readonly [P in keyof T]-?: T[P] };
>T11 : T11<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T12<T> = { -readonly [P in keyof T]: T[P] };
>T12 : T12<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T13<T> = { -readonly [P in keyof T]?: T[P] };
>T13 : T13<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T14<T> = { -readonly [P in keyof T]+?: T[P] };
>T14 : T14<T>
>T : T
>P : P
>T : T
>T : T
>P : P
type T15<T> = { -readonly [P in keyof T]-?: T[P] };
>T15 : T15<T>
>T : T
>P : P
>T : T
>T : T
>P : P
function f1<T>(x: Required<T>, y: T, z: Partial<T>) {
>f1 : <T>(x: Required<T>, y: T, z: Partial<T>) => void
>T : T
>x : Required<T>
>Required : Required<T>
>T : T
>y : T
>T : T
>z : Partial<T>
>Partial : Partial<T>
>T : T
x = x;
>x = x : Required<T>
>x : Required<T>
>x : Required<T>
x = y; // Error
>x = y : T
>x : Required<T>
>y : T
x = z; // Error
>x = z : Partial<T>
>x : Required<T>
>z : Partial<T>
y = x;
>y = x : Required<T>
>y : T
>x : Required<T>
y = y;
>y = y : T
>y : T
>y : T
y = z; // Error
>y = z : Partial<T>
>y : T
>z : Partial<T>
z = x;
>z = x : Required<T>
>z : Partial<T>
>x : Required<T>
z = y;
>z = y : T
>z : Partial<T>
>y : T
z = z;
>z = z : Partial<T>
>z : Partial<T>
>z : Partial<T>
}
type Denullified<T> = { [P in keyof T]-?: NonNullable<T[P]> };
>Denullified : Denullified<T>
>T : T
>P : P
>T : T
>NonNullable : NonNullable<T>
>T : T
>P : P
function f2<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) {
>f2 : <T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) => void
>T : T
>w : Denullified<T>
>Denullified : Denullified<T>
>T : T
>x : Required<T>
>Required : Required<T>
>T : T
>y : T
>T : T
>z : Partial<T>
>Partial : Partial<T>
>T : T
w = w;
>w = w : Denullified<T>
>w : Denullified<T>
>w : Denullified<T>
w = x; // Error
>w = x : Required<T>
>w : Denullified<T>
>x : Required<T>
w = y; // Error
>w = y : T
>w : Denullified<T>
>y : T
w = z; // Error
>w = z : Partial<T>
>w : Denullified<T>
>z : Partial<T>
x = w;
>x = w : Denullified<T>
>x : Required<T>
>w : Denullified<T>
x = x;
>x = x : Required<T>
>x : Required<T>
>x : Required<T>
x = y; // Error
>x = y : T
>x : Required<T>
>y : T
x = z; // Error
>x = z : Partial<T>
>x : Required<T>
>z : Partial<T>
y = w;
>y = w : Denullified<T>
>y : T
>w : Denullified<T>
y = x;
>y = x : Required<T>
>y : T
>x : Required<T>
y = y;
>y = y : T
>y : T
>y : T
y = z; // Error
>y = z : Partial<T>
>y : T
>z : Partial<T>
z = w;
>z = w : Denullified<T>
>z : Partial<T>
>w : Denullified<T>
z = x;
>z = x : Required<T>
>z : Partial<T>
>x : Required<T>
z = y;
>z = y : T
>z : Partial<T>
>y : T
z = z;
>z = z : Partial<T>
>z : Partial<T>
>z : Partial<T>
}
function f3<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) {
>f3 : <T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) => void
>T : T
>w : Denullified<T>
>Denullified : Denullified<T>
>T : T
>x : Required<T>
>Required : Required<T>
>T : T
>y : T
>T : T
>z : Partial<T>
>Partial : Partial<T>
>T : T
w = {}; // Error
>w = {} : {}
>w : Denullified<T>
>{} : {}
x = {}; // Error
>x = {} : {}
>x : Required<T>
>{} : {}
y = {}; // Error
>y = {} : {}
>y : T
>{} : {}
z = {};
>z = {} : {}
>z : Partial<T>
>{} : {}
}
type Readwrite<T> = {
>Readwrite : Readwrite<T>
>T : T
-readonly [P in keyof T]: T[P];
>P : P
>T : T
>T : T
>P : P
}
function f10<T>(x: Readonly<T>, y: T, z: Readwrite<T>) {
>f10 : <T>(x: Readonly<T>, y: T, z: Readwrite<T>) => void
>T : T
>x : Readonly<T>
>Readonly : Readonly<T>
>T : T
>y : T
>T : T
>z : Readwrite<T>
>Readwrite : Readwrite<T>
>T : T
x = x;
>x = x : Readonly<T>
>x : Readonly<T>
>x : Readonly<T>
x = y;
>x = y : T
>x : Readonly<T>
>y : T
x = z;
>x = z : Readwrite<T>
>x : Readonly<T>
>z : Readwrite<T>
y = x;
>y = x : Readonly<T>
>y : T
>x : Readonly<T>
y = y;
>y = y : T
>y : T
>y : T
y = z;
>y = z : Readwrite<T>
>y : T
>z : Readwrite<T>
z = x;
>z = x : Readonly<T>
>z : Readwrite<T>
>x : Readonly<T>
z = y;
>z = y : T
>z : Readwrite<T>
>y : T
z = z;
>z = z : Readwrite<T>
>z : Readwrite<T>
>z : Readwrite<T>
}
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<Foo>;
>x2 : Required<Foo>
>Required : Required<T>
>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<Foo>
>{ 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<Foo>
>{ 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<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
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<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
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<Bar>;
>x4 : Readonly<Bar>
>Readonly : Readonly<T>
>Bar : Bar
x4.a = 1; // Error
>x4.a = 1 : 1
>x4.a : any
>x4 : Readonly<Bar>
>a : any
>1 : 1
x4.b = 1; // Error
>x4.b = 1 : 1
>x4.b : any
>x4 : Readonly<Bar>
>b : any
>1 : 1
declare let x5: Readwrite<Bar>;
>x5 : Readwrite<Bar>
>Readwrite : Readwrite<T>
>Bar : Bar
x5.a = 1;
>x5.a = 1 : 1
>x5.a : number
>x5 : Readwrite<Bar>
>a : number
>1 : 1
x5.b = 1;
>x5.b = 1 : 1
>x5.b : number
>x5 : Readwrite<Bar>
>b : number
>1 : 1
@@ -0,0 +1,127 @@
// @strict: true
// @declaration: true
type T00<T> = { [P in keyof T]: T[P] };
type T01<T> = { [P in keyof T]?: T[P] };
type T02<T> = { [P in keyof T]+?: T[P] };
type T03<T> = { [P in keyof T]-?: T[P] };
type T04<T> = { readonly [P in keyof T]: T[P] };
type T05<T> = { readonly [P in keyof T]?: T[P] };
type T06<T> = { readonly [P in keyof T]+?: T[P] };
type T07<T> = { readonly [P in keyof T]-?: T[P] };
type T08<T> = { +readonly [P in keyof T]: T[P] };
type T09<T> = { +readonly [P in keyof T]?: T[P] };
type T10<T> = { +readonly [P in keyof T]+?: T[P] };
type T11<T> = { +readonly [P in keyof T]-?: T[P] };
type T12<T> = { -readonly [P in keyof T]: T[P] };
type T13<T> = { -readonly [P in keyof T]?: T[P] };
type T14<T> = { -readonly [P in keyof T]+?: T[P] };
type T15<T> = { -readonly [P in keyof T]-?: T[P] };
function f1<T>(x: Required<T>, y: T, z: Partial<T>) {
x = x;
x = y; // Error
x = z; // Error
y = x;
y = y;
y = z; // Error
z = x;
z = y;
z = z;
}
type Denullified<T> = { [P in keyof T]-?: NonNullable<T[P]> };
function f2<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) {
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<T>(w: Denullified<T>, x: Required<T>, y: T, z: Partial<T>) {
w = {}; // Error
x = {}; // Error
y = {}; // Error
z = {};
}
type Readwrite<T> = {
-readonly [P in keyof T]: T[P];
}
function f10<T>(x: Readonly<T>, y: T, z: Readwrite<T>) {
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<Foo>;
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<Bar>;
x4.a = 1; // Error
x4.b = 1; // Error
declare let x5: Readwrite<Bar>;
x5.a = 1;
x5.b = 1;