Add 'T extends U' type operator

This commit is contained in:
Anders Hejlsberg
2017-12-12 09:52:14 -08:00
parent 063eed1a47
commit ec2bdfdb8b
10 changed files with 213 additions and 71 deletions
+1
View File
@@ -3422,6 +3422,7 @@ namespace ts {
case SyntaxKind.TypeAliasDeclaration:
case SyntaxKind.ThisType:
case SyntaxKind.TypeOperator:
case SyntaxKind.BinaryType:
case SyntaxKind.IndexedAccessType:
case SyntaxKind.MappedType:
case SyntaxKind.LiteralType:
+109 -33
View File
@@ -264,6 +264,8 @@ namespace ts {
const intersectionTypes = createMap<IntersectionType>();
const literalTypes = createMap<LiteralType>();
const indexedAccessTypes = createMap<IndexedAccessType>();
const conditionalTypes = createMap<ConditionalType>();
const extendsTypes = createMap<ExtendsType>();
const evolvingArrayTypes: EvolvingArrayType[] = [];
const undefinedProperties = createMap<Symbol>() as UnderscoreEscapedMap<Symbol>;
@@ -2621,11 +2623,15 @@ namespace ts {
return createIndexedAccessTypeNode(objectTypeNode, indexTypeNode);
}
if (type.flags & TypeFlags.Conditional) {
const checkTypeNode = typeToTypeNodeHelper((<ConditionalType>type).checkType, context);
const extendskTypeNode = typeToTypeNodeHelper((<ConditionalType>type).extendsType, context);
const conditionTypeNode = typeToTypeNodeHelper((<ConditionalType>type).conditionType, context);
const trueTypeNode = typeToTypeNodeHelper((<ConditionalType>type).trueType, context);
const falseTypeNode = typeToTypeNodeHelper((<ConditionalType>type).falseType, context);
return createConditionalTypeNode(checkTypeNode, extendskTypeNode, trueTypeNode, falseTypeNode);
return createConditionalTypeNode(conditionTypeNode, trueTypeNode, falseTypeNode);
}
if (type.flags & TypeFlags.Extends) {
const leftTypeNode = typeToTypeNodeHelper((<ExtendsType>type).checkType, context);
const rightTypeNode = typeToTypeNodeHelper((<ExtendsType>type).extendsType, context);
return createBinaryTypeNode(leftTypeNode, SyntaxKind.ExtendsKeyword, rightTypeNode);
}
Debug.fail("Should be unreachable.");
@@ -3396,11 +3402,7 @@ namespace ts {
writePunctuation(writer, SyntaxKind.CloseBracketToken);
}
else if (type.flags & TypeFlags.Conditional) {
writeType((<ConditionalType>type).checkType, TypeFormatFlags.InElementType);
writeSpace(writer);
writer.writeKeyword("extends");
writeSpace(writer);
writeType((<ConditionalType>type).extendsType, TypeFormatFlags.InElementType);
writeType((<ConditionalType>type).conditionType, TypeFormatFlags.InElementType);
writeSpace(writer);
writePunctuation(writer, SyntaxKind.QuestionToken);
writeSpace(writer);
@@ -3410,6 +3412,13 @@ namespace ts {
writeSpace(writer);
writeType((<ConditionalType>type).falseType, TypeFormatFlags.InElementType);
}
else if (type.flags & TypeFlags.Extends) {
writeType((<ExtendsType>type).checkType, TypeFormatFlags.InElementType);
writeSpace(writer);
writer.writeKeyword("extends");
writeSpace(writer);
writeType((<ExtendsType>type).extendsType, TypeFormatFlags.InElementType);
}
else {
// Should never get here
// { ... }
@@ -6385,6 +6394,9 @@ namespace ts {
const falseBaseType = getBaseConstraint((<ConditionalType>t).trueType);
return trueBaseType && falseBaseType ? getUnionType([trueBaseType, falseBaseType]) : undefined;
}
if (t.flags & TypeFlags.Extends) {
return booleanType;
}
if (isGenericMappedType(t)) {
return emptyObjectType;
}
@@ -8109,6 +8121,12 @@ namespace ts {
false;
}
function isGenericConditionType(type: Type): boolean {
return type.flags & (TypeFlags.TypeVariable | TypeFlags.Extends) ? true :
type.flags & TypeFlags.UnionOrIntersection ? forEach((<UnionOrIntersectionType>type).types, isGenericConditionType) :
false;
}
// Return true if the given type is a non-generic object type with a string index signature and no
// other members.
function isStringIndexOnlyType(type: Type) {
@@ -8216,33 +8234,73 @@ namespace ts {
return links.resolvedType;
}
function getConditionalType(checkType: Type, extendsType: Type, trueType: Type, falseType: Type, aliasSymbol?: Symbol, aliasTypeArguments?: Type[]): Type {
if (checkType.flags & TypeFlags.Union) {
return getUnionType(map((<UnionType>checkType).types, t => getConditionalType(t, extendsType, trueType, falseType)),
/*subtypeReduction*/ false, aliasSymbol, aliasTypeArguments);
}
if (isTypeAssignableTo(checkType, extendsType)) {
return trueType;
}
if (!isGenericObjectType(checkType) && !isGenericObjectType(extendsType)) {
return falseType;
}
function createConditionalType(conditionType: Type, whenTrueType: Type, whenFalseType: Type, aliasSymbol: Symbol, aliasTypeArguments: Type[]) {
const type = <ConditionalType>createType(TypeFlags.Conditional);
type.checkType = checkType;
type.extendsType = extendsType;
type.trueType = trueType;
type.falseType = falseType;
type.conditionType = conditionType;
type.trueType = whenTrueType;
type.falseType = whenFalseType;
type.aliasSymbol = aliasSymbol;
type.aliasTypeArguments = aliasTypeArguments;
return type;
}
function getConditionalType(condition: Type, whenTrue: Type, whenFalse: Type, aliasSymbol: Symbol, aliasTypeArguments: Type[], mapper: TypeMapper): Type {
if (!isGenericConditionType(condition)) {
return condition.flags & TypeFlags.Never ? neverType : getUnionType([
typeMaybeAssignableTo(condition, trueType) ? instantiateType(whenTrue, mapper) : neverType,
typeMaybeAssignableTo(condition, falseType) ? instantiateType(whenFalse, mapper) : neverType]);
}
const resultTrueType = instantiateType(whenTrue, mapper);
const resultFalseType = instantiateType(whenFalse, mapper);
const resultTypeArguments = instantiateTypes(aliasTypeArguments, mapper);
const id = condition.id + "," + resultTrueType.id + "," + resultFalseType.id;
let type = conditionalTypes.get(id);
if (!type) {
conditionalTypes.set(id, type = createConditionalType(condition, resultTrueType, resultFalseType, aliasSymbol, resultTypeArguments));
}
return type;
}
function getTypeFromConditionalTypeNode(node: ConditionalTypeNode): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
links.resolvedType = getConditionalType(getTypeFromTypeNode(node.checkType), getTypeFromTypeNode(node.extendsType),
links.resolvedType = getConditionalType(getTypeFromTypeNode(node.conditionType),
getTypeFromTypeNode(node.trueType), getTypeFromTypeNode(node.falseType),
getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node));
getAliasSymbolForTypeNode(node), getAliasTypeArgumentsForTypeNode(node), identityMapper);
}
return links.resolvedType;
}
function createExtendsType(checkType: Type, extendsType: Type) {
const type = <ExtendsType>createType(TypeFlags.Extends);
type.checkType = checkType;
type.extendsType = extendsType;
return type;
}
function getExtendsType(checkType: Type, extendsType: Type): Type {
// sys.write(`getExtendsType(${typeToString(checkType)}, ${typeToString(extendsType)})\n`);
if (checkType.flags & TypeFlags.Union) {
return getUnionType(map((<UnionType>checkType).types, t => getExtendsType(t, extendsType)), /*subtypeReduction*/ false);
}
if (checkType.flags & TypeFlags.Any) {
return booleanType;
}
if (!isGenericObjectType(checkType) && !isGenericObjectType(extendsType)) {
return isTypeAssignableTo(checkType, extendsType) ? trueType : falseType;
}
const id = checkType.id + "," + extendsType.id;
let type = extendsTypes.get(id);
if (!type) {
extendsTypes.set(id, type = createExtendsType(checkType, extendsType));
}
return type;
}
function getTypeFromBinaryTypeNode(node: BinaryTypeNode): Type {
const links = getNodeLinks(node);
if (!links.resolvedType) {
links.resolvedType = getExtendsType(getTypeFromTypeNode(node.left), getTypeFromTypeNode(node.right));
}
return links.resolvedType;
}
@@ -8541,6 +8599,8 @@ namespace ts {
return getTypeFromMappedTypeNode(<MappedTypeNode>node);
case SyntaxKind.ConditionalType:
return getTypeFromConditionalTypeNode(<ConditionalTypeNode>node);
case SyntaxKind.BinaryType:
return getTypeFromBinaryTypeNode(<BinaryTypeNode>node);
// This function assumes that an identifier or qualified name is a type expression
// Callers should first ensure this by calling isTypeNode
case SyntaxKind.Identifier:
@@ -8807,20 +8867,23 @@ namespace ts {
}
function getConditionalTypeInstantiation(type: ConditionalType, mapper: TypeMapper): Type {
const checkType = type.checkType;
if (checkType.flags & TypeFlags.TypeParameter) {
const instantiatedType = mapper(<TypeParameter>checkType);
if (checkType !== instantiatedType && instantiatedType.flags & TypeFlags.Union) {
return mapType(instantiatedType, t => instantiateConditionalType(type, createReplacementMapper(checkType, t, mapper)));
const conditionType = type.conditionType;
if (conditionType.flags & TypeFlags.Extends) {
const checkType = (<ExtendsType>conditionType).checkType;
if (checkType.flags & TypeFlags.TypeParameter) {
const instantiatedType = mapper(<TypeParameter>checkType);
if (checkType !== instantiatedType && instantiatedType.flags & TypeFlags.Union) {
return mapType(instantiatedType, t => instantiateConditionalType(type, createReplacementMapper(checkType, t, mapper)));
}
}
}
return instantiateConditionalType(type, mapper);
}
function instantiateConditionalType(type: ConditionalType, mapper: TypeMapper): Type {
return getConditionalType(instantiateType((<ConditionalType>type).checkType, mapper), instantiateType((<ConditionalType>type).extendsType, mapper),
instantiateType((<ConditionalType>type).trueType, mapper), instantiateType((<ConditionalType>type).falseType, mapper),
type.aliasSymbol, instantiateTypes(type.aliasTypeArguments, mapper));
return getConditionalType(instantiateType((<ConditionalType>type).conditionType, mapper),
(<ConditionalType>type).trueType, (<ConditionalType>type).falseType,
type.aliasSymbol, type.aliasTypeArguments, mapper);
}
function instantiateType(type: Type, mapper: TypeMapper): Type {
@@ -8858,6 +8921,9 @@ namespace ts {
if (type.flags & TypeFlags.Conditional) {
return getConditionalTypeInstantiation(<ConditionalType>type, mapper);
}
if (type.flags & TypeFlags.Extends) {
return getExtendsType(instantiateType((<ExtendsType>type).checkType, mapper), instantiateType((<ExtendsType>type).extendsType, mapper));
}
}
return type;
}
@@ -20047,6 +20113,11 @@ namespace ts {
checkSourceElement(node.type);
}
function checkConditionalType(node: ConditionalTypeNode) {
forEachChild(node, checkSourceElement);
checkTypeAssignableTo(getTypeFromTypeNode(node.conditionType), booleanType, node.conditionType);
}
function isPrivateWithinAmbient(node: Node): boolean {
return hasModifier(node, ModifierFlags.Private) && !!(node.flags & NodeFlags.Ambient);
}
@@ -23687,6 +23758,11 @@ namespace ts {
return checkSourceElement((<ParenthesizedTypeNode | TypeOperatorNode>node).type);
case SyntaxKind.TypeOperator:
return checkTypeOperator(<TypeOperatorNode>node);
case SyntaxKind.ConditionalType:
return checkConditionalType(<ConditionalTypeNode>node);
case SyntaxKind.BinaryType:
forEachChild(node, checkSourceElement);
return;
case SyntaxKind.JSDocAugmentsTag:
return checkJSDocAugmentsTag(node as JSDocAugmentsTag);
case SyntaxKind.JSDocTypedefTag:
+10 -4
View File
@@ -456,6 +456,8 @@ namespace ts {
return emitParenType(<ParenthesizedTypeNode>type);
case SyntaxKind.TypeOperator:
return emitTypeOperator(<TypeOperatorNode>type);
case SyntaxKind.BinaryType:
return emitBinaryType(<BinaryTypeNode>type);
case SyntaxKind.IndexedAccessType:
return emitIndexedAccessType(<IndexedAccessTypeNode>type);
case SyntaxKind.MappedType:
@@ -548,16 +550,14 @@ namespace ts {
}
function emitConditionalType(node: ConditionalTypeNode) {
emitType(node.checkType);
write(" extends ");
emitType(node.extendsType);
emitType(node.conditionType);
write(" ? ");
emitType(node.trueType);
write(" : ");
emitType(node.falseType);
}
function emitParenType(type: ParenthesizedTypeNode) {
function emitParenType(type: ParenthesizedTypeNode) {
write("(");
emitType(type.type);
write(")");
@@ -569,6 +569,12 @@ namespace ts {
emitType(type.type);
}
function emitBinaryType(node: BinaryTypeNode) {
emitType(node.left);
write(" extends ");
emitType(node.right);
}
function emitIndexedAccessType(node: IndexedAccessTypeNode) {
emitType(node.objectType);
write("[");
+9 -3
View File
@@ -572,6 +572,8 @@ namespace ts {
return emitThisType();
case SyntaxKind.TypeOperator:
return emitTypeOperator(<TypeOperatorNode>node);
case SyntaxKind.BinaryType:
return emitBinaryType(<BinaryTypeNode>node);
case SyntaxKind.IndexedAccessType:
return emitIndexedAccessType(<IndexedAccessTypeNode>node);
case SyntaxKind.MappedType:
@@ -1132,9 +1134,7 @@ namespace ts {
}
function emitConditionalType(node: ConditionalTypeNode) {
emit(node.checkType);
write(" extends ");
emit(node.extendsType);
emit(node.conditionType);
write(" ? ");
emit(node.trueType);
write(" : ");
@@ -1157,6 +1157,12 @@ namespace ts {
emit(node.type);
}
function emitBinaryType(node: BinaryTypeNode) {
emit(node.left);
write(" extends ");
emit(node.right);
}
function emitIndexedAccessType(node: IndexedAccessTypeNode) {
emit(node.objectType);
write("[");
+26 -8
View File
@@ -720,21 +720,19 @@ namespace ts {
: node;
}
export function createConditionalTypeNode(checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) {
export function createConditionalTypeNode(conditionType: TypeNode, trueType: TypeNode, falseType: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.ConditionalType) as ConditionalTypeNode;
node.checkType = parenthesizeConditionalTypeMember(checkType);
node.extendsType = parenthesizeConditionalTypeMember(extendsType);
node.conditionType = parenthesizeConditionalTypeMember(conditionType);
node.trueType = trueType;
node.falseType = falseType;
return node;
}
export function updateConditionalTypeNode(node: ConditionalTypeNode, checkType: TypeNode, extendsType: TypeNode, trueType: TypeNode, falseType: TypeNode) {
return node.checkType !== checkType
|| node.extendsType !== extendsType
export function updateConditionalTypeNode(node: ConditionalTypeNode, conditionType: TypeNode, trueType: TypeNode, falseType: TypeNode) {
return node.conditionType !== conditionType
|| node.trueType !== trueType
|| node.falseType !== falseType
? updateNode(createConditionalTypeNode(checkType, extendsType, trueType, falseType), node)
? updateNode(createConditionalTypeNode(conditionType, trueType, falseType), node)
: node;
}
@@ -767,6 +765,22 @@ namespace ts {
return node.type !== type ? updateNode(createTypeOperatorNode(node.operator, type), node) : node;
}
export function createBinaryTypeNode(left: TypeNode, operator: SyntaxKind.ExtendsKeyword, right: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.BinaryType) as BinaryTypeNode;
node.left = parenthesizeBinaryTypeMember(left);
node.operator = operator;
node.right = parenthesizeBinaryTypeMember(right);
return node;
}
export function updateBinaryTypeNode(node: BinaryTypeNode, left: TypeNode, operator: SyntaxKind.ExtendsKeyword, right: TypeNode) {
return node.left !== left
|| node.operator !== operator
|| node.right !== right
? updateNode(createBinaryTypeNode(left, operator, right), node)
: node;
}
export function createIndexedAccessTypeNode(objectType: TypeNode, indexType: TypeNode) {
const node = createSynthesizedNode(SyntaxKind.IndexedAccessType) as IndexedAccessTypeNode;
node.objectType = parenthesizeElementTypeMember(objectType);
@@ -4103,6 +4117,10 @@ namespace ts {
return member.kind === SyntaxKind.ConditionalType ? createParenthesizedType(member) : member;
}
export function parenthesizeBinaryTypeMember(member: TypeNode) {
return member.kind === SyntaxKind.BinaryType ? createParenthesizedType(member) : parenthesizeConditionalTypeMember(member);
}
export function parenthesizeElementTypeMember(member: TypeNode) {
switch (member.kind) {
case SyntaxKind.UnionType:
@@ -4111,7 +4129,7 @@ namespace ts {
case SyntaxKind.ConstructorType:
return createParenthesizedType(member);
}
return parenthesizeConditionalTypeMember(member);
return parenthesizeBinaryTypeMember(member);
}
export function parenthesizeArrayTypeMember(member: TypeNode) {
+19 -7
View File
@@ -148,13 +148,15 @@ namespace ts {
case SyntaxKind.IntersectionType:
return visitNodes(cbNode, cbNodes, (<UnionOrIntersectionTypeNode>node).types);
case SyntaxKind.ConditionalType:
return visitNode(cbNode, (<ConditionalTypeNode>node).checkType) ||
visitNode(cbNode, (<ConditionalTypeNode>node).extendsType) ||
return visitNode(cbNode, (<ConditionalTypeNode>node).conditionType) ||
visitNode(cbNode, (<ConditionalTypeNode>node).trueType) ||
visitNode(cbNode, (<ConditionalTypeNode>node).falseType);
case SyntaxKind.ParenthesizedType:
case SyntaxKind.TypeOperator:
return visitNode(cbNode, (<ParenthesizedTypeNode | TypeOperatorNode>node).type);
case SyntaxKind.BinaryType:
return visitNode(cbNode, (<BinaryTypeNode>node).left) ||
visitNode(cbNode, (<BinaryTypeNode>node).right);
case SyntaxKind.IndexedAccessType:
return visitNode(cbNode, (<IndexedAccessTypeNode>node).objectType) ||
visitNode(cbNode, (<IndexedAccessTypeNode>node).indexType);
@@ -2848,13 +2850,23 @@ namespace ts {
return parseUnionOrIntersectionType(SyntaxKind.UnionType, parseIntersectionTypeOrHigher, SyntaxKind.BarToken);
}
function parseBinaryTypeOrHigher(): TypeNode {
let type = parseUnionTypeOrHigher();
while (parseOptional(SyntaxKind.ExtendsKeyword)) {
const node = <BinaryTypeNode>createNode(SyntaxKind.BinaryType, type.pos);
node.left = type;
node.operator = SyntaxKind.ExtendsKeyword;
node.right = parseUnionTypeOrHigher();
type = finishNode(node);
}
return type;
}
function parseConditionalTypeOrHigher(): TypeNode {
const type = parseUnionTypeOrHigher();
if (parseOptional(SyntaxKind.ExtendsKeyword)) {
const type = parseBinaryTypeOrHigher();
if (parseOptional(SyntaxKind.QuestionToken)) {
const node = <ConditionalTypeNode>createNode(SyntaxKind.ConditionalType, type.pos);
node.checkType = type;
node.extendsType = parseUnionTypeOrHigher();
parseExpected(SyntaxKind.QuestionToken);
node.conditionType = type;
node.trueType = parseConditionalTypeOrHigher();
parseExpected(SyntaxKind.ColonToken);
node.falseType = parseConditionalTypeOrHigher();
+2
View File
@@ -389,6 +389,7 @@ namespace ts {
case SyntaxKind.ParenthesizedType:
case SyntaxKind.ThisType:
case SyntaxKind.TypeOperator:
case SyntaxKind.BinaryType:
case SyntaxKind.IndexedAccessType:
case SyntaxKind.MappedType:
case SyntaxKind.LiteralType:
@@ -1886,6 +1887,7 @@ namespace ts {
case SyntaxKind.TypeQuery:
case SyntaxKind.TypeOperator:
case SyntaxKind.BinaryType:
case SyntaxKind.IndexedAccessType:
case SyntaxKind.MappedType:
case SyntaxKind.TypeLiteral:
+26 -14
View File
@@ -252,6 +252,7 @@ namespace ts {
ParenthesizedType,
ThisType,
TypeOperator,
BinaryType,
IndexedAccessType,
MappedType,
LiteralType,
@@ -1068,8 +1069,7 @@ namespace ts {
export interface ConditionalTypeNode extends TypeNode {
kind: SyntaxKind.ConditionalType;
checkType: TypeNode;
extendsType: TypeNode;
conditionType: TypeNode;
trueType: TypeNode;
falseType: TypeNode;
}
@@ -1085,6 +1085,13 @@ namespace ts {
type: TypeNode;
}
export interface BinaryTypeNode extends TypeNode {
kind: SyntaxKind.BinaryType;
left: TypeNode;
operator: SyntaxKind.ExtendsKeyword;
right: TypeNode;
}
/* @internal */
export interface UniqueTypeOperatorNode extends TypeOperatorNode {
operator: SyntaxKind.UniqueKeyword;
@@ -3348,19 +3355,20 @@ namespace ts {
Intersection = 1 << 18, // Intersection (T & U)
Index = 1 << 19, // keyof T
IndexedAccess = 1 << 20, // T[K]
Conditional = 1 << 21, // A extends B ? T : U
Conditional = 1 << 21, // C ? T : U
Extends = 1 << 22, // T extends U
/* @internal */
FreshLiteral = 1 << 22, // Fresh literal or unique type
FreshLiteral = 1 << 23, // Fresh literal or unique type
/* @internal */
ContainsWideningType = 1 << 23, // Type is or contains undefined or null widening type
ContainsWideningType = 1 << 24, // Type is or contains undefined or null widening type
/* @internal */
ContainsObjectLiteral = 1 << 24, // Type is or contains object literal type
ContainsObjectLiteral = 1 << 25, // Type is or contains object literal type
/* @internal */
ContainsAnyFunctionType = 1 << 25, // Type is or contains the anyFunctionType
NonPrimitive = 1 << 26, // intrinsic object type
ContainsAnyFunctionType = 1 << 26, // Type is or contains the anyFunctionType
NonPrimitive = 1 << 27, // intrinsic object type
/* @internal */
JsxAttributes = 1 << 27, // Jsx attributes type
MarkerType = 1 << 28, // Marker type used for variance probing
JsxAttributes = 1 << 28, // Jsx attributes type
MarkerType = 1 << 29, // Marker type used for variance probing
/* @internal */
Nullable = Undefined | Null,
@@ -3378,13 +3386,13 @@ namespace ts {
Primitive = String | Number | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol,
StringLike = String | StringLiteral | Index,
NumberLike = Number | NumberLiteral | Enum,
BooleanLike = Boolean | BooleanLiteral,
BooleanLike = Boolean | BooleanLiteral | Extends,
EnumLike = Enum | EnumLiteral,
ESSymbolLike = ESSymbol | UniqueESSymbol,
UnionOrIntersection = Union | Intersection,
StructuredType = Object | Union | Intersection,
TypeVariable = TypeParameter | IndexedAccess | Conditional,
StructuredOrTypeVariable = StructuredType | TypeVariable | Index,
StructuredOrTypeVariable = StructuredType | TypeVariable | Index | Extends,
// 'Narrowable' types are types where narrowing actually narrows.
// This *should* be every type other than null, undefined, void, and never
@@ -3637,12 +3645,16 @@ namespace ts {
}
export interface ConditionalType extends TypeVariable {
checkType: Type;
extendsType: Type;
conditionType: Type;
trueType: Type;
falseType: Type;
}
export interface ExtendsType extends TypeVariable {
checkType: Type;
extendsType: Type;
}
export const enum SignatureKind {
Call,
Construct,
+4
View File
@@ -4543,6 +4543,10 @@ namespace ts {
return node.kind === SyntaxKind.TypeOperator;
}
export function isBinaryTypeNode(node: Node): node is BinaryTypeNode {
return node.kind === SyntaxKind.BinaryType;
}
export function isIndexedAccessTypeNode(node: Node): node is IndexedAccessTypeNode {
return node.kind === SyntaxKind.IndexedAccessType;
}
+7 -2
View File
@@ -387,8 +387,7 @@ namespace ts {
case SyntaxKind.ConditionalType:
return updateConditionalTypeNode(<ConditionalTypeNode>node,
visitNode((<ConditionalTypeNode>node).checkType, visitor, isTypeNode),
visitNode((<ConditionalTypeNode>node).extendsType, visitor, isTypeNode),
visitNode((<ConditionalTypeNode>node).conditionType, visitor, isTypeNode),
visitNode((<ConditionalTypeNode>node).trueType, visitor, isTypeNode),
visitNode((<ConditionalTypeNode>node).falseType, visitor, isTypeNode));
@@ -400,6 +399,12 @@ namespace ts {
return updateTypeOperatorNode(<TypeOperatorNode>node,
visitNode((<TypeOperatorNode>node).type, visitor, isTypeNode));
case SyntaxKind.BinaryType:
return updateBinaryTypeNode(<BinaryTypeNode>node,
visitNode((<BinaryTypeNode>node).left, visitor, isTypeNode),
(<BinaryTypeNode>node).operator,
visitNode((<BinaryTypeNode>node).right, visitor, isTypeNode));
case SyntaxKind.IndexedAccessType:
return updateIndexedAccessTypeNode((<IndexedAccessTypeNode>node),
visitNode((<IndexedAccessTypeNode>node).objectType, visitor, isTypeNode),