@@ -3732,11 +3732,16 @@ namespace ts {
3732
3732
return getObjectFlags(type) & ObjectFlags.Reference ? (<TypeReference>type).target : type;
3733
3733
}
3734
3734
3735
- function hasBaseType(type: InterfaceType , checkBase: InterfaceType ) {
3735
+ function hasBaseType(type: BaseType , checkBase: BaseType ) {
3736
3736
return check(type);
3737
- function check(type: InterfaceType): boolean {
3738
- const target = <InterfaceType>getTargetType(type);
3739
- return target === checkBase || forEach(getBaseTypes(target), check);
3737
+ function check(type: BaseType): boolean {
3738
+ if (getObjectFlags(type) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) {
3739
+ const target = <InterfaceType>getTargetType(type);
3740
+ return target === checkBase || forEach(getBaseTypes(target), check);
3741
+ }
3742
+ else if (type.flags & TypeFlags.Intersection) {
3743
+ return forEach((<IntersectionType>type).types, check);
3744
+ }
3740
3745
}
3741
3746
}
3742
3747
@@ -3862,7 +3867,7 @@ namespace ts {
3862
3867
return type.resolvedBaseConstructorType;
3863
3868
}
3864
3869
3865
- function getBaseTypes(type: InterfaceType): ObjectType [] {
3870
+ function getBaseTypes(type: InterfaceType): BaseType [] {
3866
3871
if (!type.resolvedBaseTypes) {
3867
3872
if (type.objectFlags & ObjectFlags.Tuple) {
3868
3873
type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters))];
@@ -3922,11 +3927,11 @@ namespace ts {
3922
3927
if (baseType === unknownType) {
3923
3928
return;
3924
3929
}
3925
- if (!(getObjectFlags(getTargetType( baseType)) & ObjectFlags.ClassOrInterface )) {
3930
+ if (!isValidBaseType( baseType)) {
3926
3931
error(baseTypeNode.expression, Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType));
3927
3932
return;
3928
3933
}
3929
- if (type === baseType || hasBaseType(<InterfaceType >baseType, type)) {
3934
+ if (type === baseType || hasBaseType(<BaseType >baseType, type)) {
3930
3935
error(valueDecl, Diagnostics.Type_0_recursively_references_itself_as_a_base_type,
3931
3936
typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType));
3932
3937
return;
@@ -3951,15 +3956,22 @@ namespace ts {
3951
3956
return true;
3952
3957
}
3953
3958
3959
+ // A valid base type is any non-generic object type or intersection of non-generic
3960
+ // object types.
3961
+ function isValidBaseType(type: Type): boolean {
3962
+ return type.flags & TypeFlags.Object && !isGenericMappedType(type) ||
3963
+ type.flags & TypeFlags.Intersection && !forEach((<IntersectionType>type).types, t => !isValidBaseType(t));
3964
+ }
3965
+
3954
3966
function resolveBaseTypesOfInterface(type: InterfaceType): void {
3955
3967
type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray;
3956
3968
for (const declaration of type.symbol.declarations) {
3957
3969
if (declaration.kind === SyntaxKind.InterfaceDeclaration && getInterfaceBaseTypeNodes(<InterfaceDeclaration>declaration)) {
3958
3970
for (const node of getInterfaceBaseTypeNodes(<InterfaceDeclaration>declaration)) {
3959
3971
const baseType = getTypeFromTypeNode(node);
3960
3972
if (baseType !== unknownType) {
3961
- if (getObjectFlags(getTargetType( baseType)) & ObjectFlags.ClassOrInterface ) {
3962
- if (type !== baseType && !hasBaseType(<InterfaceType >baseType, type)) {
3973
+ if (isValidBaseType( baseType)) {
3974
+ if (type !== baseType && !hasBaseType(<BaseType >baseType, type)) {
3963
3975
if (type.resolvedBaseTypes === emptyArray) {
3964
3976
type.resolvedBaseTypes = [<ObjectType>baseType];
3965
3977
}
@@ -4317,6 +4329,9 @@ namespace ts {
4317
4329
return createTypeReference((<TypeReference>type).target,
4318
4330
concatenate((<TypeReference>type).typeArguments, [thisArgument || (<TypeReference>type).target.thisType]));
4319
4331
}
4332
+ if (type.flags & TypeFlags.Intersection) {
4333
+ return getIntersectionType(map((<IntersectionType>type).types, t => getTypeWithThisArgument(t, thisArgument)));
4334
+ }
4320
4335
return type;
4321
4336
}
4322
4337
@@ -4350,8 +4365,8 @@ namespace ts {
4350
4365
}
4351
4366
const thisArgument = lastOrUndefined(typeArguments);
4352
4367
for (const baseType of baseTypes) {
4353
- const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(<ObjectType> instantiateType(baseType, mapper), thisArgument) : baseType;
4354
- addInheritedMembers(members, getPropertiesOfObjectType (instantiatedBaseType));
4368
+ const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType;
4369
+ addInheritedMembers(members, getPropertiesOfType (instantiatedBaseType));
4355
4370
callSignatures = concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Call));
4356
4371
constructSignatures = concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Construct));
4357
4372
stringIndexInfo = stringIndexInfo || getIndexInfoOfType(instantiatedBaseType, IndexKind.String);
@@ -18216,16 +18231,18 @@ namespace ts {
18216
18231
return;
18217
18232
}
18218
18233
18234
+ const propDeclaration = prop.valueDeclaration;
18235
+
18219
18236
// index is numeric and property name is not valid numeric literal
18220
- if (indexKind === IndexKind.Number && !isNumericName(prop.valueDeclaration .name)) {
18237
+ if (indexKind === IndexKind.Number && propDeclaration && !isNumericName(propDeclaration .name)) {
18221
18238
return;
18222
18239
}
18223
18240
18224
18241
// perform property check if property or indexer is declared in 'type'
18225
18242
// this allows to rule out cases when both property and indexer are inherited from the base class
18226
18243
let errorNode: Node;
18227
- if (prop.valueDeclaration .name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) {
18228
- errorNode = prop.valueDeclaration ;
18244
+ if (propDeclaration && propDeclaration .name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) {
18245
+ errorNode = propDeclaration ;
18229
18246
}
18230
18247
else if (indexDeclaration) {
18231
18248
errorNode = indexDeclaration;
@@ -18364,7 +18381,7 @@ namespace ts {
18364
18381
checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node,
18365
18382
Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1);
18366
18383
18367
- if (baseType.symbol.valueDeclaration &&
18384
+ if (baseType.symbol && baseType.symbol .valueDeclaration &&
18368
18385
!isInAmbientContext(baseType.symbol.valueDeclaration) &&
18369
18386
baseType.symbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration) {
18370
18387
if (!isBlockScopedNameDeclaredBeforeUse(baseType.symbol.valueDeclaration, node)) {
@@ -18437,7 +18454,7 @@ namespace ts {
18437
18454
return forEach(symbol.declarations, d => isClassLike(d) ? d : undefined);
18438
18455
}
18439
18456
18440
- function checkKindsOfPropertyMemberOverrides(type: InterfaceType, baseType: ObjectType ): void {
18457
+ function checkKindsOfPropertyMemberOverrides(type: InterfaceType, baseType: BaseType ): void {
18441
18458
18442
18459
// TypeScript 1.0 spec (April 2014): 8.2.3
18443
18460
// A derived class inherits all members from its base class it doesn't override.
@@ -18454,7 +18471,7 @@ namespace ts {
18454
18471
// derived class instance member variables and accessors, but not by other kinds of members.
18455
18472
18456
18473
// NOTE: assignability is checked in checkClassDeclaration
18457
- const baseProperties = getPropertiesOfObjectType (baseType);
18474
+ const baseProperties = getPropertiesOfType (baseType);
18458
18475
for (const baseProperty of baseProperties) {
18459
18476
const base = getTargetSymbol(baseProperty);
18460
18477
@@ -18578,7 +18595,7 @@ namespace ts {
18578
18595
let ok = true;
18579
18596
18580
18597
for (const base of baseTypes) {
18581
- const properties = getPropertiesOfObjectType (getTypeWithThisArgument(base, type.thisType));
18598
+ const properties = getPropertiesOfType (getTypeWithThisArgument(base, type.thisType));
18582
18599
for (const prop of properties) {
18583
18600
const existing = seen.get(prop.name);
18584
18601
if (!existing) {
0 commit comments