mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-09 02:30:15 -06:00
Allow +/- to prefix 'readonly' and '?' modifiers in mapped types
This commit is contained in:
parent
74f01abfcf
commit
a629acd8fd
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user