From a6c5306479d1ca150657967f77fa2a195db4b793 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 19 Jan 2017 13:58:09 -0800 Subject: [PATCH 1/9] Allow object intersection types as class/interface base types --- src/compiler/checker.ts | 53 ++++++++++++++++++++++++++-------------- src/compiler/types.ts | 7 ++++-- src/services/services.ts | 2 +- src/services/types.ts | 2 +- 4 files changed, 42 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 756a2b2d3b191..9cc5fb111cddb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3732,11 +3732,16 @@ namespace ts { return getObjectFlags(type) & ObjectFlags.Reference ? (type).target : type; } - function hasBaseType(type: InterfaceType, checkBase: InterfaceType) { + function hasBaseType(type: BaseType, checkBase: BaseType) { return check(type); - function check(type: InterfaceType): boolean { - const target = getTargetType(type); - return target === checkBase || forEach(getBaseTypes(target), check); + function check(type: BaseType): boolean { + if (getObjectFlags(type) & (ObjectFlags.ClassOrInterface | ObjectFlags.Reference)) { + const target = getTargetType(type); + return target === checkBase || forEach(getBaseTypes(target), check); + } + else if (type.flags & TypeFlags.Intersection) { + return forEach((type).types, check); + } } } @@ -3862,7 +3867,7 @@ namespace ts { return type.resolvedBaseConstructorType; } - function getBaseTypes(type: InterfaceType): ObjectType[] { + function getBaseTypes(type: InterfaceType): BaseType[] { if (!type.resolvedBaseTypes) { if (type.objectFlags & ObjectFlags.Tuple) { type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters))]; @@ -3922,11 +3927,11 @@ namespace ts { if (baseType === unknownType) { return; } - if (!(getObjectFlags(getTargetType(baseType)) & ObjectFlags.ClassOrInterface)) { + if (!isValidBaseType(baseType)) { error(baseTypeNode.expression, Diagnostics.Base_constructor_return_type_0_is_not_a_class_or_interface_type, typeToString(baseType)); return; } - if (type === baseType || hasBaseType(baseType, type)) { + if (type === baseType || hasBaseType(baseType, type)) { error(valueDecl, Diagnostics.Type_0_recursively_references_itself_as_a_base_type, typeToString(type, /*enclosingDeclaration*/ undefined, TypeFormatFlags.WriteArrayAsGenericType)); return; @@ -3951,6 +3956,13 @@ namespace ts { return true; } + // A valid base type is any non-generic object type or intersection of non-generic + // object types. + function isValidBaseType(type: Type): boolean { + return type.flags & TypeFlags.Object && !isGenericMappedType(type) || + type.flags & TypeFlags.Intersection && !forEach((type).types, t => !isValidBaseType(t)); + } + function resolveBaseTypesOfInterface(type: InterfaceType): void { type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; for (const declaration of type.symbol.declarations) { @@ -3958,8 +3970,8 @@ namespace ts { for (const node of getInterfaceBaseTypeNodes(declaration)) { const baseType = getTypeFromTypeNode(node); if (baseType !== unknownType) { - if (getObjectFlags(getTargetType(baseType)) & ObjectFlags.ClassOrInterface) { - if (type !== baseType && !hasBaseType(baseType, type)) { + if (isValidBaseType(baseType)) { + if (type !== baseType && !hasBaseType(baseType, type)) { if (type.resolvedBaseTypes === emptyArray) { type.resolvedBaseTypes = [baseType]; } @@ -4317,6 +4329,9 @@ namespace ts { return createTypeReference((type).target, concatenate((type).typeArguments, [thisArgument || (type).target.thisType])); } + if (type.flags & TypeFlags.Intersection) { + return getIntersectionType(map((type).types, t => getTypeWithThisArgument(t, thisArgument))); + } return type; } @@ -4350,8 +4365,8 @@ namespace ts { } const thisArgument = lastOrUndefined(typeArguments); for (const baseType of baseTypes) { - const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType; - addInheritedMembers(members, getPropertiesOfObjectType(instantiatedBaseType)); + const instantiatedBaseType = thisArgument ? getTypeWithThisArgument(instantiateType(baseType, mapper), thisArgument) : baseType; + addInheritedMembers(members, getPropertiesOfType(instantiatedBaseType)); callSignatures = concatenate(callSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Call)); constructSignatures = concatenate(constructSignatures, getSignaturesOfType(instantiatedBaseType, SignatureKind.Construct)); stringIndexInfo = stringIndexInfo || getIndexInfoOfType(instantiatedBaseType, IndexKind.String); @@ -18216,16 +18231,18 @@ namespace ts { return; } + const propDeclaration = prop.valueDeclaration; + // index is numeric and property name is not valid numeric literal - if (indexKind === IndexKind.Number && !isNumericName(prop.valueDeclaration.name)) { + if (indexKind === IndexKind.Number && propDeclaration && !isNumericName(propDeclaration.name)) { return; } // perform property check if property or indexer is declared in 'type' // this allows to rule out cases when both property and indexer are inherited from the base class let errorNode: Node; - if (prop.valueDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) { - errorNode = prop.valueDeclaration; + if (propDeclaration && propDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) { + errorNode = propDeclaration; } else if (indexDeclaration) { errorNode = indexDeclaration; @@ -18364,7 +18381,7 @@ namespace ts { checkTypeAssignableTo(staticType, getTypeWithoutSignatures(staticBaseType), node.name || node, Diagnostics.Class_static_side_0_incorrectly_extends_base_class_static_side_1); - if (baseType.symbol.valueDeclaration && + if (baseType.symbol && baseType.symbol.valueDeclaration && !isInAmbientContext(baseType.symbol.valueDeclaration) && baseType.symbol.valueDeclaration.kind === SyntaxKind.ClassDeclaration) { if (!isBlockScopedNameDeclaredBeforeUse(baseType.symbol.valueDeclaration, node)) { @@ -18437,7 +18454,7 @@ namespace ts { return forEach(symbol.declarations, d => isClassLike(d) ? d : undefined); } - function checkKindsOfPropertyMemberOverrides(type: InterfaceType, baseType: ObjectType): void { + function checkKindsOfPropertyMemberOverrides(type: InterfaceType, baseType: BaseType): void { // TypeScript 1.0 spec (April 2014): 8.2.3 // A derived class inherits all members from its base class it doesn't override. @@ -18454,7 +18471,7 @@ namespace ts { // derived class instance member variables and accessors, but not by other kinds of members. // NOTE: assignability is checked in checkClassDeclaration - const baseProperties = getPropertiesOfObjectType(baseType); + const baseProperties = getPropertiesOfType(baseType); for (const baseProperty of baseProperties) { const base = getTargetSymbol(baseProperty); @@ -18578,7 +18595,7 @@ namespace ts { let ok = true; for (const base of baseTypes) { - const properties = getPropertiesOfObjectType(getTypeWithThisArgument(base, type.thisType)); + const properties = getPropertiesOfType(getTypeWithThisArgument(base, type.thisType)); for (const prop of properties) { const existing = seen.get(prop.name); if (!existing) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 51347c8d3df5b..b834d73300a3e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2358,7 +2358,7 @@ getIndexInfoOfType(type: Type, kind: IndexKind): IndexInfo; getSignaturesOfType(type: Type, kind: SignatureKind): Signature[]; getIndexTypeOfType(type: Type, kind: IndexKind): Type; - getBaseTypes(type: InterfaceType): ObjectType[]; + getBaseTypes(type: InterfaceType): BaseType[]; getReturnTypeOfSignature(signature: Signature): Type; /** * Gets the type of a parameter at a given position in a signature. @@ -2910,9 +2910,12 @@ /* @internal */ resolvedBaseConstructorType?: Type; // Resolved base constructor type of class /* @internal */ - resolvedBaseTypes: ObjectType[]; // Resolved base types + resolvedBaseTypes: BaseType[]; // Resolved base types } + // Object type or intersection of object types + export type BaseType = ObjectType | IntersectionType; + export interface InterfaceTypeWithDeclaredMembers extends InterfaceType { declaredProperties: Symbol[]; // Declared members declaredCallSignatures: Signature[]; // Declared call signatures diff --git a/src/services/services.ts b/src/services/services.ts index 26374eccbfddb..04cb233557fec 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -379,7 +379,7 @@ namespace ts { getNumberIndexType(): Type { return this.checker.getIndexTypeOfType(this, IndexKind.Number); } - getBaseTypes(): ObjectType[] { + getBaseTypes(): BaseType[] { return this.flags & TypeFlags.Object && this.objectFlags & (ObjectFlags.Class | ObjectFlags.Interface) ? this.checker.getBaseTypes(this) : undefined; diff --git a/src/services/types.ts b/src/services/types.ts index 88ffe2950ced8..f410eb5b40131 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -33,7 +33,7 @@ namespace ts { getConstructSignatures(): Signature[]; getStringIndexType(): Type; getNumberIndexType(): Type; - getBaseTypes(): ObjectType[]; + getBaseTypes(): BaseType[]; getNonNullableType(): Type; } From 1c2f7f866bd19d8ebbf3a4fe35b096bf512efba2 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 19 Jan 2017 14:30:53 -0800 Subject: [PATCH 2/9] Improve efficiency of union/intersection resolved property caching --- src/compiler/checker.ts | 40 +++++++++++++++++++--------------------- src/compiler/types.ts | 4 +++- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 9cc5fb111cddb..1ca1cd9cf7496 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4754,28 +4754,26 @@ namespace ts { } function getPropertiesOfUnionOrIntersectionType(type: UnionOrIntersectionType): Symbol[] { - for (const current of type.types) { - for (const prop of getPropertiesOfType(current)) { - getUnionOrIntersectionProperty(type, prop.name); - } - // The properties of a union type are those that are present in all constituent types, so - // we only need to check the properties of the first type - if (type.flags & TypeFlags.Union) { - break; - } - } - const props = type.resolvedProperties; - if (props) { - const result: Symbol[] = []; - props.forEach(prop => { - // We need to filter out partial properties in union types - if (!(prop.flags & SymbolFlags.SyntheticProperty && (prop).isPartial)) { - result.push(prop); + if (!type.resolvedProperties) { + const members = createMap(); + for (const current of type.types) { + for (const prop of getPropertiesOfType(current)) { + if (!members.has(prop.name)) { + const combinedProp = getPropertyOfUnionOrIntersectionType(type, prop.name); + if (combinedProp) { + members.set(prop.name, combinedProp); + } + } } - }); - return result; + // The properties of a union type are those that are present in all constituent types, so + // we only need to check the properties of the first type + if (type.flags & TypeFlags.Union) { + break; + } + } + type.resolvedProperties = getNamedMembers(members); } - return emptyArray; + return type.resolvedProperties; } function getPropertiesOfType(type: Type): Symbol[] { @@ -4943,7 +4941,7 @@ namespace ts { // these partial properties when identifying discriminant properties, but otherwise they are filtered out // and do not appear to be present in the union type. function getUnionOrIntersectionProperty(type: UnionOrIntersectionType, name: string): Symbol { - const properties = type.resolvedProperties || (type.resolvedProperties = createMap()); + const properties = type.propertyCache || (type.propertyCache = createMap()); let property = properties.get(name); if (!property) { property = createUnionOrIntersectionProperty(type, name); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b834d73300a3e..65cd40316138a 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2948,7 +2948,9 @@ export interface UnionOrIntersectionType extends Type { types: Type[]; // Constituent types /* @internal */ - resolvedProperties: SymbolTable; // Cache of resolved properties + propertyCache: SymbolTable; // Cache of resolved properties + /* @internal */ + resolvedProperties: Symbol[]; /* @internal */ resolvedIndexType: IndexType; /* @internal */ From c51e2867f50de63db151310da03b829d667becc9 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 19 Jan 2017 14:47:26 -0800 Subject: [PATCH 3/9] Allow object intersection types in class implements clauses --- src/compiler/checker.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1ca1cd9cf7496..450fcfe1da4e2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18411,8 +18411,7 @@ namespace ts { if (produceDiagnostics) { const t = getTypeFromTypeNode(typeRefNode); if (t !== unknownType) { - const declaredType = getObjectFlags(t) & ObjectFlags.Reference ? (t).target : t; - if (getObjectFlags(declaredType) & ObjectFlags.ClassOrInterface) { + if (isValidBaseType(t)) { checkTypeAssignableTo(typeWithThis, getTypeWithThisArgument(t, type.thisType), node.name || node, Diagnostics.Class_0_incorrectly_implements_interface_1); } else { From f9a65e436c67b1da2e0a80274e1fba5a9afc6d61 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Thu, 19 Jan 2017 14:47:38 -0800 Subject: [PATCH 4/9] Accept new baselines --- .../reference/typeAliasesForObjectTypes.errors.txt | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt b/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt index d5bc01f93baee..b4ae59780498b 100644 --- a/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt +++ b/tests/baselines/reference/typeAliasesForObjectTypes.errors.txt @@ -1,19 +1,13 @@ -tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(4,22): error TS2312: An interface may only extend a class or another interface. -tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(5,21): error TS2422: A class may only implement another class or interface. tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(10,6): error TS2300: Duplicate identifier 'T2'. tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts(11,6): error TS2300: Duplicate identifier 'T2'. -==== tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts (4 errors) ==== +==== tests/cases/conformance/types/typeAliases/typeAliasesForObjectTypes.ts (2 errors) ==== type T1 = { x: string } // An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot. interface I1 extends T1 { y: string } - ~~ -!!! error TS2312: An interface may only extend a class or another interface. class C1 implements T1 { - ~~ -!!! error TS2422: A class may only implement another class or interface. x: string; } From a9af10b030d2167ad7612a98df28f4084e95a005 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Jan 2017 06:16:08 -0800 Subject: [PATCH 5/9] Intersections as their own 'this' type --- src/compiler/checker.ts | 16 ++++++++++++---- src/compiler/core.ts | 4 ++++ src/compiler/types.ts | 5 ++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 450fcfe1da4e2..6de1b5aa624fb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -4326,10 +4326,13 @@ namespace ts { function getTypeWithThisArgument(type: Type, thisArgument?: Type): Type { if (getObjectFlags(type) & ObjectFlags.Reference) { - return createTypeReference((type).target, - concatenate((type).typeArguments, [thisArgument || (type).target.thisType])); + const target = (type).target; + const typeArguments = (type).typeArguments; + if (length(target.typeParameters) === length(typeArguments)) { + return createTypeReference(target, concatenate(typeArguments, [thisArgument || target.thisType])); + } } - if (type.flags & TypeFlags.Intersection) { + else if (type.flags & TypeFlags.Intersection) { return getIntersectionType(map((type).types, t => getTypeWithThisArgument(t, thisArgument))); } return type; @@ -4858,6 +4861,10 @@ namespace ts { } } + function getApparentTypeOfIntersectionType(type: IntersectionType) { + return type.resolvedIndexType || (type.resolvedApparentType = getTypeWithThisArgument(type, type)); + } + /** * For a type parameter, return the base constraint of the type parameter. For the string, number, * boolean, and symbol primitive types, return the corresponding object types. Otherwise return the @@ -4865,7 +4872,8 @@ namespace ts { */ function getApparentType(type: Type): Type { const t = type.flags & TypeFlags.TypeVariable ? getBaseConstraintOfType(type) || emptyObjectType : type; - return t.flags & TypeFlags.StringLike ? globalStringType : + return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(type) : + t.flags & TypeFlags.StringLike ? globalStringType : t.flags & TypeFlags.NumberLike ? globalNumberType : t.flags & TypeFlags.BooleanLike ? globalBooleanType : t.flags & TypeFlags.ESSymbol ? getGlobalESSymbolType() : diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 654b1bc291273..47a6e2e70a843 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -202,6 +202,10 @@ namespace ts { GreaterThan = 1 } + export function length(array: any[]) { + return array ? array.length : 0; + } + /** * Iterates through 'array' by index and performs the callback on each element of array until the callback * returns a truthy value, then returns that value. diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 65cd40316138a..6b5c670a9fad7 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -2961,7 +2961,10 @@ export interface UnionType extends UnionOrIntersectionType { } - export interface IntersectionType extends UnionOrIntersectionType { } + export interface IntersectionType extends UnionOrIntersectionType { + /* @internal */ + resolvedApparentType: Type; + } export type StructuredType = ObjectType | UnionType | IntersectionType; From c16c7d56c0a4e9f7e11dd134cffcdbb1eef5916c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Fri, 20 Jan 2017 09:17:14 -0800 Subject: [PATCH 6/9] Allow base constructor types to be intersections --- src/compiler/checker.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6de1b5aa624fb..a5058bdf7f212 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3810,7 +3810,7 @@ namespace ts { } function isConstructorType(type: Type): boolean { - return type.flags & TypeFlags.Object && getSignaturesOfType(type, SignatureKind.Construct).length > 0; + return isValidBaseType(type) && getSignaturesOfType(type, SignatureKind.Construct).length > 0; } function getBaseTypeNodeOfClass(type: InterfaceType): ExpressionWithTypeArguments { @@ -3849,7 +3849,7 @@ namespace ts { return unknownType; } const baseConstructorType = checkExpression(baseTypeNode.expression); - if (baseConstructorType.flags & TypeFlags.Object) { + if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) { // Resolving the members of a class requires us to resolve the base class of that class. // We force resolution here such that we catch circularities now. resolveStructuredTypeMembers(baseConstructorType); @@ -3890,7 +3890,7 @@ namespace ts { function resolveBaseTypesOfClass(type: InterfaceType): void { type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; const baseConstructorType = getBaseConstructorTypeOfClass(type); - if (!(baseConstructorType.flags & TypeFlags.Object)) { + if (!(baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection))) { return; } const baseTypeNode = getBaseTypeNodeOfClass(type); @@ -4591,9 +4591,9 @@ namespace ts { constructSignatures = getDefaultConstructSignatures(classType); } const baseConstructorType = getBaseConstructorTypeOfClass(classType); - if (baseConstructorType.flags & TypeFlags.Object) { + if (baseConstructorType.flags & (TypeFlags.Object | TypeFlags.Intersection)) { members = createSymbolTable(getNamedMembers(members)); - addInheritedMembers(members, getPropertiesOfObjectType(baseConstructorType)); + addInheritedMembers(members, getPropertiesOfType(baseConstructorType)); } } const numberIndexInfo = symbol.flags & SymbolFlags.Enum ? enumNumberIndexInfo : undefined; From ad71da0a7f36fafa8e940c388fd503c60ae6afee Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 21 Jan 2017 13:06:54 -0800 Subject: [PATCH 7/9] Fix error reporting bug --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a5058bdf7f212..3242a30d38140 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18240,14 +18240,14 @@ namespace ts { const propDeclaration = prop.valueDeclaration; // index is numeric and property name is not valid numeric literal - if (indexKind === IndexKind.Number && propDeclaration && !isNumericName(propDeclaration.name)) { + if (indexKind === IndexKind.Number && !(propDeclaration ? isNumericName(propDeclaration.name) : isNumericLiteralName(prop.name))) { return; } // perform property check if property or indexer is declared in 'type' // this allows to rule out cases when both property and indexer are inherited from the base class let errorNode: Node; - if (propDeclaration && propDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol) { + if (propDeclaration && (propDeclaration.name.kind === SyntaxKind.ComputedPropertyName || prop.parent === containingType.symbol)) { errorNode = propDeclaration; } else if (indexDeclaration) { From 615784ad944a3e7ec392e6043c41028558aab5b4 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 21 Jan 2017 13:07:06 -0800 Subject: [PATCH 8/9] Add tests --- .../interfaceExtendsObjectIntersection.ts | 55 +++++++++++++++++++ ...nterfaceExtendsObjectIntersectionErrors.ts | 49 +++++++++++++++++ .../intersection/intersectionThisTypes.ts | 40 ++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts create mode 100644 tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts create mode 100644 tests/cases/conformance/types/intersection/intersectionThisTypes.ts diff --git a/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts new file mode 100644 index 0000000000000..003976a2b27c8 --- /dev/null +++ b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts @@ -0,0 +1,55 @@ +// @strictNullChecks: true + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = () => void; +type T4 = new () => { a: number }; +type T5 = number[]; +type T6 = [string, number]; +type T7 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { x: string } +interface I2 extends T2 { x: string } +interface I3 extends T3 { x: string } +interface I4 extends T4 { x: string } +interface I5 extends T5 { x: string } +interface I6 extends T6 { x: string } +interface I7 extends T7 { x: string } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { x: string } +class C2 extends Constructor() { x: string } +class C3 extends Constructor() { x: string } +class C4 extends Constructor() { x: string } +class C5 extends Constructor() { x: string } +class C6 extends Constructor() { x: string } +class C7 extends Constructor() { x: string } + +declare function fx(x: string): string; +declare class CX { a: number } +declare enum EX { A, B, C } +declare namespace NX { export const a = 1 } + +type T10 = typeof fx; +type T11 = typeof CX; +type T12 = typeof EX; +type T13 = typeof NX; + +interface I10 extends T10 { x: string } +interface I11 extends T11 { x: string } +interface I12 extends T12 { x: string } +interface I13 extends T13 { x: string } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { x: string } +interface I21 extends Readonly { x: string } +interface I22 extends Identifiable { x: string } +interface I23 extends Identifiable { x: string } + +class C20 extends Constructor>() { x: string } +class C21 extends Constructor>() { x: string } +class C22 extends Constructor>() { x: string } +class C23 extends Constructor>() { x: string } diff --git a/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts new file mode 100644 index 0000000000000..5a2a37fc22754 --- /dev/null +++ b/tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts @@ -0,0 +1,49 @@ +// @strictNullChecks: true + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = number[]; +type T4 = [string, number]; +type T5 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { a: string } +interface I2 extends T2 { b: string } +interface I3 extends T3 { length: string } +interface I4 extends T4 { 0: number } +interface I5 extends T5 { c: number } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { a: string } +class C2 extends Constructor() { b: string } +class C3 extends Constructor() { length: string } +class C4 extends Constructor() { 0: number } +class C5 extends Constructor() { c: number } + +declare class CX { static a: string } +declare enum EX { A, B, C } +declare namespace NX { export const a = "hello" } + +type TCX = typeof CX; +type TEX = typeof EX; +type TNX = typeof NX; + +interface I10 extends TCX { a: number } +interface I11 extends TEX { C: string } +interface I12 extends TNX { a: number } +interface I14 extends TCX { [x: string]: number } +interface I15 extends TEX { [x: string]: number } +interface I16 extends TNX { [x: string]: number } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { a: string } +interface I21 extends Readonly { a: string } +interface I22 extends Identifiable { a: string } +interface I23 extends Identifiable { a: string } + +type U = { a: number } | { b: string }; + +interface I30 extends U { x: string } +interface I31 extends T { x: string } diff --git a/tests/cases/conformance/types/intersection/intersectionThisTypes.ts b/tests/cases/conformance/types/intersection/intersectionThisTypes.ts new file mode 100644 index 0000000000000..8819148dc9e91 --- /dev/null +++ b/tests/cases/conformance/types/intersection/intersectionThisTypes.ts @@ -0,0 +1,40 @@ +interface Thing1 { + a: number; + self(): this; +} + +interface Thing2 { + b: number; + me(): this; +} + +type Thing3 = Thing1 & Thing2; +type Thing4 = Thing3 & string[]; + +function f1(t: Thing3) { + t = t.self(); + t = t.me().self().me(); +} + +interface Thing5 extends Thing4 { + c: string; +} + +function f2(t: Thing5) { + t = t.self(); + t = t.me().self().me(); +} + +interface Component { + extend(props: T): this & T; +} + +interface Label extends Component { + title: string; +} + +function test(label: Label) { + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); + extended.id; // Ok + extended.tag; // Ok +} From 3a34cb3088632f2361b7adafdb16fe802febcd8e Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Sat, 21 Jan 2017 13:12:02 -0800 Subject: [PATCH 9/9] Accept new baselines --- .../interfaceExtendsObjectIntersection.js | 145 +++++++++++ ...interfaceExtendsObjectIntersection.symbols | 230 +++++++++++++++++ .../interfaceExtendsObjectIntersection.types | 242 ++++++++++++++++++ ...ExtendsObjectIntersectionErrors.errors.txt | 197 ++++++++++++++ ...nterfaceExtendsObjectIntersectionErrors.js | 97 +++++++ .../reference/intersectionThisTypes.js | 57 +++++ .../reference/intersectionThisTypes.symbols | 127 +++++++++ .../reference/intersectionThisTypes.types | 145 +++++++++++ 8 files changed, 1240 insertions(+) create mode 100644 tests/baselines/reference/interfaceExtendsObjectIntersection.js create mode 100644 tests/baselines/reference/interfaceExtendsObjectIntersection.symbols create mode 100644 tests/baselines/reference/interfaceExtendsObjectIntersection.types create mode 100644 tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt create mode 100644 tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js create mode 100644 tests/baselines/reference/intersectionThisTypes.js create mode 100644 tests/baselines/reference/intersectionThisTypes.symbols create mode 100644 tests/baselines/reference/intersectionThisTypes.types diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersection.js b/tests/baselines/reference/interfaceExtendsObjectIntersection.js new file mode 100644 index 0000000000000..a6fb62f5070f8 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersection.js @@ -0,0 +1,145 @@ +//// [interfaceExtendsObjectIntersection.ts] + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = () => void; +type T4 = new () => { a: number }; +type T5 = number[]; +type T6 = [string, number]; +type T7 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { x: string } +interface I2 extends T2 { x: string } +interface I3 extends T3 { x: string } +interface I4 extends T4 { x: string } +interface I5 extends T5 { x: string } +interface I6 extends T6 { x: string } +interface I7 extends T7 { x: string } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { x: string } +class C2 extends Constructor() { x: string } +class C3 extends Constructor() { x: string } +class C4 extends Constructor() { x: string } +class C5 extends Constructor() { x: string } +class C6 extends Constructor() { x: string } +class C7 extends Constructor() { x: string } + +declare function fx(x: string): string; +declare class CX { a: number } +declare enum EX { A, B, C } +declare namespace NX { export const a = 1 } + +type T10 = typeof fx; +type T11 = typeof CX; +type T12 = typeof EX; +type T13 = typeof NX; + +interface I10 extends T10 { x: string } +interface I11 extends T11 { x: string } +interface I12 extends T12 { x: string } +interface I13 extends T13 { x: string } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { x: string } +interface I21 extends Readonly { x: string } +interface I22 extends Identifiable { x: string } +interface I23 extends Identifiable { x: string } + +class C20 extends Constructor>() { x: string } +class C21 extends Constructor>() { x: string } +class C22 extends Constructor>() { x: string } +class C23 extends Constructor>() { x: string } + + +//// [interfaceExtendsObjectIntersection.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var C1 = (function (_super) { + __extends(C1, _super); + function C1() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C1; +}(Constructor())); +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C2; +}(Constructor())); +var C3 = (function (_super) { + __extends(C3, _super); + function C3() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C3; +}(Constructor())); +var C4 = (function (_super) { + __extends(C4, _super); + function C4() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C4; +}(Constructor())); +var C5 = (function (_super) { + __extends(C5, _super); + function C5() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C5; +}(Constructor())); +var C6 = (function (_super) { + __extends(C6, _super); + function C6() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C6; +}(Constructor())); +var C7 = (function (_super) { + __extends(C7, _super); + function C7() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C7; +}(Constructor())); +var C20 = (function (_super) { + __extends(C20, _super); + function C20() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C20; +}(Constructor())); +var C21 = (function (_super) { + __extends(C21, _super); + function C21() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C21; +}(Constructor())); +var C22 = (function (_super) { + __extends(C22, _super); + function C22() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C22; +}(Constructor())); +var C23 = (function (_super) { + __extends(C23, _super); + function C23() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C23; +}(Constructor())); diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersection.symbols b/tests/baselines/reference/interfaceExtendsObjectIntersection.symbols new file mode 100644 index 0000000000000..16c8c51cf47c4 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersection.symbols @@ -0,0 +1,230 @@ +=== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts === + +type T1 = { a: number }; +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>a : Symbol(a, Decl(interfaceExtendsObjectIntersection.ts, 1, 11)) + +type T2 = T1 & { b: number }; +>T2 : Symbol(T2, Decl(interfaceExtendsObjectIntersection.ts, 1, 24)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>b : Symbol(b, Decl(interfaceExtendsObjectIntersection.ts, 2, 16)) + +type T3 = () => void; +>T3 : Symbol(T3, Decl(interfaceExtendsObjectIntersection.ts, 2, 29)) + +type T4 = new () => { a: number }; +>T4 : Symbol(T4, Decl(interfaceExtendsObjectIntersection.ts, 3, 21)) +>a : Symbol(a, Decl(interfaceExtendsObjectIntersection.ts, 4, 21)) + +type T5 = number[]; +>T5 : Symbol(T5, Decl(interfaceExtendsObjectIntersection.ts, 4, 34)) + +type T6 = [string, number]; +>T6 : Symbol(T6, Decl(interfaceExtendsObjectIntersection.ts, 5, 19)) + +type T7 = { [P in 'a' | 'b' | 'c']: string }; +>T7 : Symbol(T7, Decl(interfaceExtendsObjectIntersection.ts, 6, 27)) +>P : Symbol(P, Decl(interfaceExtendsObjectIntersection.ts, 7, 13)) + +interface I1 extends T1 { x: string } +>I1 : Symbol(I1, Decl(interfaceExtendsObjectIntersection.ts, 7, 45)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I1.x, Decl(interfaceExtendsObjectIntersection.ts, 9, 25)) + +interface I2 extends T2 { x: string } +>I2 : Symbol(I2, Decl(interfaceExtendsObjectIntersection.ts, 9, 37)) +>T2 : Symbol(T2, Decl(interfaceExtendsObjectIntersection.ts, 1, 24)) +>x : Symbol(I2.x, Decl(interfaceExtendsObjectIntersection.ts, 10, 25)) + +interface I3 extends T3 { x: string } +>I3 : Symbol(I3, Decl(interfaceExtendsObjectIntersection.ts, 10, 37)) +>T3 : Symbol(T3, Decl(interfaceExtendsObjectIntersection.ts, 2, 29)) +>x : Symbol(I3.x, Decl(interfaceExtendsObjectIntersection.ts, 11, 25)) + +interface I4 extends T4 { x: string } +>I4 : Symbol(I4, Decl(interfaceExtendsObjectIntersection.ts, 11, 37)) +>T4 : Symbol(T4, Decl(interfaceExtendsObjectIntersection.ts, 3, 21)) +>x : Symbol(I4.x, Decl(interfaceExtendsObjectIntersection.ts, 12, 25)) + +interface I5 extends T5 { x: string } +>I5 : Symbol(I5, Decl(interfaceExtendsObjectIntersection.ts, 12, 37)) +>T5 : Symbol(T5, Decl(interfaceExtendsObjectIntersection.ts, 4, 34)) +>x : Symbol(I5.x, Decl(interfaceExtendsObjectIntersection.ts, 13, 25)) + +interface I6 extends T6 { x: string } +>I6 : Symbol(I6, Decl(interfaceExtendsObjectIntersection.ts, 13, 37)) +>T6 : Symbol(T6, Decl(interfaceExtendsObjectIntersection.ts, 5, 19)) +>x : Symbol(I6.x, Decl(interfaceExtendsObjectIntersection.ts, 14, 25)) + +interface I7 extends T7 { x: string } +>I7 : Symbol(I7, Decl(interfaceExtendsObjectIntersection.ts, 14, 37)) +>T7 : Symbol(T7, Decl(interfaceExtendsObjectIntersection.ts, 6, 27)) +>x : Symbol(I7.x, Decl(interfaceExtendsObjectIntersection.ts, 15, 25)) + +type Constructor = new () => T; +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 17, 17)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 17, 17)) + +declare function Constructor(): Constructor; +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 18, 29)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 18, 29)) + +class C1 extends Constructor() { x: string } +>C1 : Symbol(C1, Decl(interfaceExtendsObjectIntersection.ts, 18, 50)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I1 : Symbol(I1, Decl(interfaceExtendsObjectIntersection.ts, 7, 45)) +>x : Symbol(C1.x, Decl(interfaceExtendsObjectIntersection.ts, 20, 36)) + +class C2 extends Constructor() { x: string } +>C2 : Symbol(C2, Decl(interfaceExtendsObjectIntersection.ts, 20, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I2 : Symbol(I2, Decl(interfaceExtendsObjectIntersection.ts, 9, 37)) +>x : Symbol(C2.x, Decl(interfaceExtendsObjectIntersection.ts, 21, 36)) + +class C3 extends Constructor() { x: string } +>C3 : Symbol(C3, Decl(interfaceExtendsObjectIntersection.ts, 21, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I3 : Symbol(I3, Decl(interfaceExtendsObjectIntersection.ts, 10, 37)) +>x : Symbol(C3.x, Decl(interfaceExtendsObjectIntersection.ts, 22, 36)) + +class C4 extends Constructor() { x: string } +>C4 : Symbol(C4, Decl(interfaceExtendsObjectIntersection.ts, 22, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I4 : Symbol(I4, Decl(interfaceExtendsObjectIntersection.ts, 11, 37)) +>x : Symbol(C4.x, Decl(interfaceExtendsObjectIntersection.ts, 23, 36)) + +class C5 extends Constructor() { x: string } +>C5 : Symbol(C5, Decl(interfaceExtendsObjectIntersection.ts, 23, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I5 : Symbol(I5, Decl(interfaceExtendsObjectIntersection.ts, 12, 37)) +>x : Symbol(C5.x, Decl(interfaceExtendsObjectIntersection.ts, 24, 36)) + +class C6 extends Constructor() { x: string } +>C6 : Symbol(C6, Decl(interfaceExtendsObjectIntersection.ts, 24, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I6 : Symbol(I6, Decl(interfaceExtendsObjectIntersection.ts, 13, 37)) +>x : Symbol(C6.x, Decl(interfaceExtendsObjectIntersection.ts, 25, 36)) + +class C7 extends Constructor() { x: string } +>C7 : Symbol(C7, Decl(interfaceExtendsObjectIntersection.ts, 25, 48)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>I7 : Symbol(I7, Decl(interfaceExtendsObjectIntersection.ts, 14, 37)) +>x : Symbol(C7.x, Decl(interfaceExtendsObjectIntersection.ts, 26, 36)) + +declare function fx(x: string): string; +>fx : Symbol(fx, Decl(interfaceExtendsObjectIntersection.ts, 26, 48)) +>x : Symbol(x, Decl(interfaceExtendsObjectIntersection.ts, 28, 20)) + +declare class CX { a: number } +>CX : Symbol(CX, Decl(interfaceExtendsObjectIntersection.ts, 28, 39)) +>a : Symbol(CX.a, Decl(interfaceExtendsObjectIntersection.ts, 29, 18)) + +declare enum EX { A, B, C } +>EX : Symbol(EX, Decl(interfaceExtendsObjectIntersection.ts, 29, 30)) +>A : Symbol(EX.A, Decl(interfaceExtendsObjectIntersection.ts, 30, 17)) +>B : Symbol(EX.B, Decl(interfaceExtendsObjectIntersection.ts, 30, 20)) +>C : Symbol(EX.C, Decl(interfaceExtendsObjectIntersection.ts, 30, 23)) + +declare namespace NX { export const a = 1 } +>NX : Symbol(NX, Decl(interfaceExtendsObjectIntersection.ts, 30, 27)) +>a : Symbol(a, Decl(interfaceExtendsObjectIntersection.ts, 31, 35)) + +type T10 = typeof fx; +>T10 : Symbol(T10, Decl(interfaceExtendsObjectIntersection.ts, 31, 43)) +>fx : Symbol(fx, Decl(interfaceExtendsObjectIntersection.ts, 26, 48)) + +type T11 = typeof CX; +>T11 : Symbol(T11, Decl(interfaceExtendsObjectIntersection.ts, 33, 21)) +>CX : Symbol(CX, Decl(interfaceExtendsObjectIntersection.ts, 28, 39)) + +type T12 = typeof EX; +>T12 : Symbol(T12, Decl(interfaceExtendsObjectIntersection.ts, 34, 21)) +>EX : Symbol(EX, Decl(interfaceExtendsObjectIntersection.ts, 29, 30)) + +type T13 = typeof NX; +>T13 : Symbol(T13, Decl(interfaceExtendsObjectIntersection.ts, 35, 21)) +>NX : Symbol(NX, Decl(interfaceExtendsObjectIntersection.ts, 30, 27)) + +interface I10 extends T10 { x: string } +>I10 : Symbol(I10, Decl(interfaceExtendsObjectIntersection.ts, 36, 21)) +>T10 : Symbol(T10, Decl(interfaceExtendsObjectIntersection.ts, 31, 43)) +>x : Symbol(I10.x, Decl(interfaceExtendsObjectIntersection.ts, 38, 27)) + +interface I11 extends T11 { x: string } +>I11 : Symbol(I11, Decl(interfaceExtendsObjectIntersection.ts, 38, 39)) +>T11 : Symbol(T11, Decl(interfaceExtendsObjectIntersection.ts, 33, 21)) +>x : Symbol(I11.x, Decl(interfaceExtendsObjectIntersection.ts, 39, 27)) + +interface I12 extends T12 { x: string } +>I12 : Symbol(I12, Decl(interfaceExtendsObjectIntersection.ts, 39, 39)) +>T12 : Symbol(T12, Decl(interfaceExtendsObjectIntersection.ts, 34, 21)) +>x : Symbol(I12.x, Decl(interfaceExtendsObjectIntersection.ts, 40, 27)) + +interface I13 extends T13 { x: string } +>I13 : Symbol(I13, Decl(interfaceExtendsObjectIntersection.ts, 40, 39)) +>T13 : Symbol(T13, Decl(interfaceExtendsObjectIntersection.ts, 35, 21)) +>x : Symbol(I13.x, Decl(interfaceExtendsObjectIntersection.ts, 41, 27)) + +type Identifiable = { _id: string } & T; +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 43, 18)) +>_id : Symbol(_id, Decl(interfaceExtendsObjectIntersection.ts, 43, 24)) +>T : Symbol(T, Decl(interfaceExtendsObjectIntersection.ts, 43, 18)) + +interface I20 extends Partial { x: string } +>I20 : Symbol(I20, Decl(interfaceExtendsObjectIntersection.ts, 43, 43)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I20.x, Decl(interfaceExtendsObjectIntersection.ts, 45, 35)) + +interface I21 extends Readonly { x: string } +>I21 : Symbol(I21, Decl(interfaceExtendsObjectIntersection.ts, 45, 47)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I21.x, Decl(interfaceExtendsObjectIntersection.ts, 46, 36)) + +interface I22 extends Identifiable { x: string } +>I22 : Symbol(I22, Decl(interfaceExtendsObjectIntersection.ts, 46, 48)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(I22.x, Decl(interfaceExtendsObjectIntersection.ts, 47, 40)) + +interface I23 extends Identifiable { x: string } +>I23 : Symbol(I23, Decl(interfaceExtendsObjectIntersection.ts, 47, 52)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>b : Symbol(b, Decl(interfaceExtendsObjectIntersection.ts, 48, 41)) +>x : Symbol(I23.x, Decl(interfaceExtendsObjectIntersection.ts, 48, 55)) + +class C20 extends Constructor>() { x: string } +>C20 : Symbol(C20, Decl(interfaceExtendsObjectIntersection.ts, 48, 67)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Partial : Symbol(Partial, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(C20.x, Decl(interfaceExtendsObjectIntersection.ts, 50, 46)) + +class C21 extends Constructor>() { x: string } +>C21 : Symbol(C21, Decl(interfaceExtendsObjectIntersection.ts, 50, 58)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Readonly : Symbol(Readonly, Decl(lib.d.ts, --, --)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(C21.x, Decl(interfaceExtendsObjectIntersection.ts, 51, 47)) + +class C22 extends Constructor>() { x: string } +>C22 : Symbol(C22, Decl(interfaceExtendsObjectIntersection.ts, 51, 59)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>x : Symbol(C22.x, Decl(interfaceExtendsObjectIntersection.ts, 52, 51)) + +class C23 extends Constructor>() { x: string } +>C23 : Symbol(C23, Decl(interfaceExtendsObjectIntersection.ts, 52, 63)) +>Constructor : Symbol(Constructor, Decl(interfaceExtendsObjectIntersection.ts, 15, 37), Decl(interfaceExtendsObjectIntersection.ts, 17, 34)) +>Identifiable : Symbol(Identifiable, Decl(interfaceExtendsObjectIntersection.ts, 41, 39)) +>T1 : Symbol(T1, Decl(interfaceExtendsObjectIntersection.ts, 0, 0)) +>b : Symbol(b, Decl(interfaceExtendsObjectIntersection.ts, 53, 49)) +>x : Symbol(C23.x, Decl(interfaceExtendsObjectIntersection.ts, 53, 66)) + diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersection.types b/tests/baselines/reference/interfaceExtendsObjectIntersection.types new file mode 100644 index 0000000000000..1ff550df7b4d3 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersection.types @@ -0,0 +1,242 @@ +=== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersection.ts === + +type T1 = { a: number }; +>T1 : T1 +>a : number + +type T2 = T1 & { b: number }; +>T2 : T2 +>T1 : T1 +>b : number + +type T3 = () => void; +>T3 : T3 + +type T4 = new () => { a: number }; +>T4 : T4 +>a : number + +type T5 = number[]; +>T5 : number[] + +type T6 = [string, number]; +>T6 : [string, number] + +type T7 = { [P in 'a' | 'b' | 'c']: string }; +>T7 : T7 +>P : P + +interface I1 extends T1 { x: string } +>I1 : I1 +>T1 : T1 +>x : string + +interface I2 extends T2 { x: string } +>I2 : I2 +>T2 : T2 +>x : string + +interface I3 extends T3 { x: string } +>I3 : I3 +>T3 : T3 +>x : string + +interface I4 extends T4 { x: string } +>I4 : I4 +>T4 : T4 +>x : string + +interface I5 extends T5 { x: string } +>I5 : I5 +>T5 : number[] +>x : string + +interface I6 extends T6 { x: string } +>I6 : I6 +>T6 : [string, number] +>x : string + +interface I7 extends T7 { x: string } +>I7 : I7 +>T7 : T7 +>x : string + +type Constructor = new () => T; +>Constructor : Constructor +>T : T +>T : T + +declare function Constructor(): Constructor; +>Constructor : () => Constructor +>T : T +>Constructor : Constructor +>T : T + +class C1 extends Constructor() { x: string } +>C1 : C1 +>Constructor() : I1 +>Constructor : () => Constructor +>I1 : I1 +>x : string + +class C2 extends Constructor() { x: string } +>C2 : C2 +>Constructor() : I2 +>Constructor : () => Constructor +>I2 : I2 +>x : string + +class C3 extends Constructor() { x: string } +>C3 : C3 +>Constructor() : I3 +>Constructor : () => Constructor +>I3 : I3 +>x : string + +class C4 extends Constructor() { x: string } +>C4 : C4 +>Constructor() : I4 +>Constructor : () => Constructor +>I4 : I4 +>x : string + +class C5 extends Constructor() { x: string } +>C5 : C5 +>Constructor() : I5 +>Constructor : () => Constructor +>I5 : I5 +>x : string + +class C6 extends Constructor() { x: string } +>C6 : C6 +>Constructor() : I6 +>Constructor : () => Constructor +>I6 : I6 +>x : string + +class C7 extends Constructor() { x: string } +>C7 : C7 +>Constructor() : I7 +>Constructor : () => Constructor +>I7 : I7 +>x : string + +declare function fx(x: string): string; +>fx : (x: string) => string +>x : string + +declare class CX { a: number } +>CX : CX +>a : number + +declare enum EX { A, B, C } +>EX : EX +>A : EX +>B : EX +>C : EX + +declare namespace NX { export const a = 1 } +>NX : typeof NX +>a : 1 +>1 : 1 + +type T10 = typeof fx; +>T10 : (x: string) => string +>fx : (x: string) => string + +type T11 = typeof CX; +>T11 : typeof CX +>CX : typeof CX + +type T12 = typeof EX; +>T12 : typeof EX +>EX : typeof EX + +type T13 = typeof NX; +>T13 : typeof NX +>NX : typeof NX + +interface I10 extends T10 { x: string } +>I10 : I10 +>T10 : (x: string) => string +>x : string + +interface I11 extends T11 { x: string } +>I11 : I11 +>T11 : typeof CX +>x : string + +interface I12 extends T12 { x: string } +>I12 : I12 +>T12 : typeof EX +>x : string + +interface I13 extends T13 { x: string } +>I13 : I13 +>T13 : typeof NX +>x : string + +type Identifiable = { _id: string } & T; +>Identifiable : Identifiable +>T : T +>_id : string +>T : T + +interface I20 extends Partial { x: string } +>I20 : I20 +>Partial : Partial +>T1 : T1 +>x : string + +interface I21 extends Readonly { x: string } +>I21 : I21 +>Readonly : Readonly +>T1 : T1 +>x : string + +interface I22 extends Identifiable { x: string } +>I22 : I22 +>Identifiable : Identifiable +>T1 : T1 +>x : string + +interface I23 extends Identifiable { x: string } +>I23 : I23 +>Identifiable : Identifiable +>T1 : T1 +>b : number +>x : string + +class C20 extends Constructor>() { x: string } +>C20 : C20 +>Constructor>() : Partial +>Constructor : () => Constructor +>Partial : Partial +>T1 : T1 +>x : string + +class C21 extends Constructor>() { x: string } +>C21 : C21 +>Constructor>() : Readonly +>Constructor : () => Constructor +>Readonly : Readonly +>T1 : T1 +>x : string + +class C22 extends Constructor>() { x: string } +>C22 : C22 +>Constructor>() : Identifiable +>Constructor : () => Constructor +>Identifiable : Identifiable +>T1 : T1 +>x : string + +class C23 extends Constructor>() { x: string } +>C23 : C23 +>Constructor>() : Identifiable +>Constructor : () => Constructor +>Identifiable : Identifiable +>T1 : T1 +>b : number +>x : string + diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt new file mode 100644 index 0000000000000..839474b3bdca0 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.errors.txt @@ -0,0 +1,197 @@ +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(8,11): error TS2430: Interface 'I1' incorrectly extends interface 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(9,11): error TS2430: Interface 'I2' incorrectly extends interface 'T2'. + Type 'I2' is not assignable to type '{ b: number; }'. + Types of property 'b' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(10,11): error TS2430: Interface 'I3' incorrectly extends interface 'number[]'. + Types of property 'length' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(11,11): error TS2430: Interface 'I4' incorrectly extends interface '[string, number]'. + Types of property '0' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(12,11): error TS2430: Interface 'I5' incorrectly extends interface 'T5'. + Types of property 'c' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(17,7): error TS2415: Class 'C1' incorrectly extends base class 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(18,7): error TS2415: Class 'C2' incorrectly extends base class 'T2'. + Type 'C2' is not assignable to type '{ b: number; }'. + Types of property 'b' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(19,7): error TS2415: Class 'C3' incorrectly extends base class 'number[]'. + Types of property 'length' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(20,7): error TS2415: Class 'C4' incorrectly extends base class '[string, number]'. + Types of property '0' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(21,7): error TS2415: Class 'C5' incorrectly extends base class 'T5'. + Types of property 'c' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(31,11): error TS2430: Interface 'I10' incorrectly extends interface 'typeof CX'. + Types of property 'a' are incompatible. + Type 'number' is not assignable to type 'string'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(32,11): error TS2430: Interface 'I11' incorrectly extends interface 'typeof EX'. + Types of property 'C' are incompatible. + Type 'string' is not assignable to type 'EX'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(33,11): error TS2430: Interface 'I12' incorrectly extends interface 'typeof NX'. + Types of property 'a' are incompatible. + Type 'number' is not assignable to type '"hello"'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(34,29): error TS2411: Property 'a' of type 'string' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(34,29): error TS2411: Property 'prototype' of type 'CX' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(35,29): error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(36,29): error TS2411: Property 'a' of type '"hello"' is not assignable to string index type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(40,11): error TS2430: Interface 'I20' incorrectly extends interface 'Partial'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number | undefined'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(41,11): error TS2430: Interface 'I21' incorrectly extends interface 'Readonly'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(42,11): error TS2430: Interface 'I22' incorrectly extends interface 'Identifiable'. + Type 'I22' is not assignable to type 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(43,11): error TS2430: Interface 'I23' incorrectly extends interface 'Identifiable'. + Type 'I23' is not assignable to type 'T1'. + Types of property 'a' are incompatible. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(47,23): error TS2312: An interface may only extend a class or another interface. +tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts(48,26): error TS2312: An interface may only extend a class or another interface. + + +==== tests/cases/conformance/interfaces/interfaceDeclarations/interfaceExtendsObjectIntersectionErrors.ts (23 errors) ==== + + type T1 = { a: number }; + type T2 = T1 & { b: number }; + type T3 = number[]; + type T4 = [string, number]; + type T5 = { [P in 'a' | 'b' | 'c']: string }; + + interface I1 extends T1 { a: string } + ~~ +!!! error TS2430: Interface 'I1' incorrectly extends interface 'T1'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I2 extends T2 { b: string } + ~~ +!!! error TS2430: Interface 'I2' incorrectly extends interface 'T2'. +!!! error TS2430: Type 'I2' is not assignable to type '{ b: number; }'. +!!! error TS2430: Types of property 'b' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I3 extends T3 { length: string } + ~~ +!!! error TS2430: Interface 'I3' incorrectly extends interface 'number[]'. +!!! error TS2430: Types of property 'length' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I4 extends T4 { 0: number } + ~~ +!!! error TS2430: Interface 'I4' incorrectly extends interface '[string, number]'. +!!! error TS2430: Types of property '0' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. + interface I5 extends T5 { c: number } + ~~ +!!! error TS2430: Interface 'I5' incorrectly extends interface 'T5'. +!!! error TS2430: Types of property 'c' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. + + type Constructor = new () => T; + declare function Constructor(): Constructor; + + class C1 extends Constructor() { a: string } + ~~ +!!! error TS2415: Class 'C1' incorrectly extends base class 'T1'. +!!! error TS2415: Types of property 'a' are incompatible. +!!! error TS2415: Type 'string' is not assignable to type 'number'. + class C2 extends Constructor() { b: string } + ~~ +!!! error TS2415: Class 'C2' incorrectly extends base class 'T2'. +!!! error TS2415: Type 'C2' is not assignable to type '{ b: number; }'. +!!! error TS2415: Types of property 'b' are incompatible. +!!! error TS2415: Type 'string' is not assignable to type 'number'. + class C3 extends Constructor() { length: string } + ~~ +!!! error TS2415: Class 'C3' incorrectly extends base class 'number[]'. +!!! error TS2415: Types of property 'length' are incompatible. +!!! error TS2415: Type 'string' is not assignable to type 'number'. + class C4 extends Constructor() { 0: number } + ~~ +!!! error TS2415: Class 'C4' incorrectly extends base class '[string, number]'. +!!! error TS2415: Types of property '0' are incompatible. +!!! error TS2415: Type 'number' is not assignable to type 'string'. + class C5 extends Constructor() { c: number } + ~~ +!!! error TS2415: Class 'C5' incorrectly extends base class 'T5'. +!!! error TS2415: Types of property 'c' are incompatible. +!!! error TS2415: Type 'number' is not assignable to type 'string'. + + declare class CX { static a: string } + declare enum EX { A, B, C } + declare namespace NX { export const a = "hello" } + + type TCX = typeof CX; + type TEX = typeof EX; + type TNX = typeof NX; + + interface I10 extends TCX { a: number } + ~~~ +!!! error TS2430: Interface 'I10' incorrectly extends interface 'typeof CX'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type 'string'. + interface I11 extends TEX { C: string } + ~~~ +!!! error TS2430: Interface 'I11' incorrectly extends interface 'typeof EX'. +!!! error TS2430: Types of property 'C' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'EX'. + interface I12 extends TNX { a: number } + ~~~ +!!! error TS2430: Interface 'I12' incorrectly extends interface 'typeof NX'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'number' is not assignable to type '"hello"'. + interface I14 extends TCX { [x: string]: number } + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'a' of type 'string' is not assignable to string index type 'number'. + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'prototype' of type 'CX' is not assignable to string index type 'number'. + interface I15 extends TEX { [x: string]: number } + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2413: Numeric index type 'string' is not assignable to string index type 'number'. + interface I16 extends TNX { [x: string]: number } + ~~~~~~~~~~~~~~~~~~~ +!!! error TS2411: Property 'a' of type '"hello"' is not assignable to string index type 'number'. + + type Identifiable = { _id: string } & T; + + interface I20 extends Partial { a: string } + ~~~ +!!! error TS2430: Interface 'I20' incorrectly extends interface 'Partial'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number | undefined'. + interface I21 extends Readonly { a: string } + ~~~ +!!! error TS2430: Interface 'I21' incorrectly extends interface 'Readonly'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I22 extends Identifiable { a: string } + ~~~ +!!! error TS2430: Interface 'I22' incorrectly extends interface 'Identifiable'. +!!! error TS2430: Type 'I22' is not assignable to type 'T1'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + interface I23 extends Identifiable { a: string } + ~~~ +!!! error TS2430: Interface 'I23' incorrectly extends interface 'Identifiable'. +!!! error TS2430: Type 'I23' is not assignable to type 'T1'. +!!! error TS2430: Types of property 'a' are incompatible. +!!! error TS2430: Type 'string' is not assignable to type 'number'. + + type U = { a: number } | { b: string }; + + interface I30 extends U { x: string } + ~ +!!! error TS2312: An interface may only extend a class or another interface. + interface I31 extends T { x: string } + ~ +!!! error TS2312: An interface may only extend a class or another interface. + \ No newline at end of file diff --git a/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js new file mode 100644 index 0000000000000..61f84b2f7feb7 --- /dev/null +++ b/tests/baselines/reference/interfaceExtendsObjectIntersectionErrors.js @@ -0,0 +1,97 @@ +//// [interfaceExtendsObjectIntersectionErrors.ts] + +type T1 = { a: number }; +type T2 = T1 & { b: number }; +type T3 = number[]; +type T4 = [string, number]; +type T5 = { [P in 'a' | 'b' | 'c']: string }; + +interface I1 extends T1 { a: string } +interface I2 extends T2 { b: string } +interface I3 extends T3 { length: string } +interface I4 extends T4 { 0: number } +interface I5 extends T5 { c: number } + +type Constructor = new () => T; +declare function Constructor(): Constructor; + +class C1 extends Constructor() { a: string } +class C2 extends Constructor() { b: string } +class C3 extends Constructor() { length: string } +class C4 extends Constructor() { 0: number } +class C5 extends Constructor() { c: number } + +declare class CX { static a: string } +declare enum EX { A, B, C } +declare namespace NX { export const a = "hello" } + +type TCX = typeof CX; +type TEX = typeof EX; +type TNX = typeof NX; + +interface I10 extends TCX { a: number } +interface I11 extends TEX { C: string } +interface I12 extends TNX { a: number } +interface I14 extends TCX { [x: string]: number } +interface I15 extends TEX { [x: string]: number } +interface I16 extends TNX { [x: string]: number } + +type Identifiable = { _id: string } & T; + +interface I20 extends Partial { a: string } +interface I21 extends Readonly { a: string } +interface I22 extends Identifiable { a: string } +interface I23 extends Identifiable { a: string } + +type U = { a: number } | { b: string }; + +interface I30 extends U { x: string } +interface I31 extends T { x: string } + + +//// [interfaceExtendsObjectIntersectionErrors.js] +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +var C1 = (function (_super) { + __extends(C1, _super); + function C1() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C1; +}(Constructor())); +var C2 = (function (_super) { + __extends(C2, _super); + function C2() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C2; +}(Constructor())); +var C3 = (function (_super) { + __extends(C3, _super); + function C3() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C3; +}(Constructor())); +var C4 = (function (_super) { + __extends(C4, _super); + function C4() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C4; +}(Constructor())); +var C5 = (function (_super) { + __extends(C5, _super); + function C5() { + return _super !== null && _super.apply(this, arguments) || this; + } + return C5; +}(Constructor())); diff --git a/tests/baselines/reference/intersectionThisTypes.js b/tests/baselines/reference/intersectionThisTypes.js new file mode 100644 index 0000000000000..9c7be09eeb838 --- /dev/null +++ b/tests/baselines/reference/intersectionThisTypes.js @@ -0,0 +1,57 @@ +//// [intersectionThisTypes.ts] +interface Thing1 { + a: number; + self(): this; +} + +interface Thing2 { + b: number; + me(): this; +} + +type Thing3 = Thing1 & Thing2; +type Thing4 = Thing3 & string[]; + +function f1(t: Thing3) { + t = t.self(); + t = t.me().self().me(); +} + +interface Thing5 extends Thing4 { + c: string; +} + +function f2(t: Thing5) { + t = t.self(); + t = t.me().self().me(); +} + +interface Component { + extend(props: T): this & T; +} + +interface Label extends Component { + title: string; +} + +function test(label: Label) { + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); + extended.id; // Ok + extended.tag; // Ok +} + + +//// [intersectionThisTypes.js] +function f1(t) { + t = t.self(); + t = t.me().self().me(); +} +function f2(t) { + t = t.self(); + t = t.me().self().me(); +} +function test(label) { + var extended = label.extend({ id: 67 }).extend({ tag: "hello" }); + extended.id; // Ok + extended.tag; // Ok +} diff --git a/tests/baselines/reference/intersectionThisTypes.symbols b/tests/baselines/reference/intersectionThisTypes.symbols new file mode 100644 index 0000000000000..8a8a6cd54965c --- /dev/null +++ b/tests/baselines/reference/intersectionThisTypes.symbols @@ -0,0 +1,127 @@ +=== tests/cases/conformance/types/intersection/intersectionThisTypes.ts === +interface Thing1 { +>Thing1 : Symbol(Thing1, Decl(intersectionThisTypes.ts, 0, 0)) + + a: number; +>a : Symbol(Thing1.a, Decl(intersectionThisTypes.ts, 0, 18)) + + self(): this; +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +} + +interface Thing2 { +>Thing2 : Symbol(Thing2, Decl(intersectionThisTypes.ts, 3, 1)) + + b: number; +>b : Symbol(Thing2.b, Decl(intersectionThisTypes.ts, 5, 18)) + + me(): this; +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +} + +type Thing3 = Thing1 & Thing2; +>Thing3 : Symbol(Thing3, Decl(intersectionThisTypes.ts, 8, 1)) +>Thing1 : Symbol(Thing1, Decl(intersectionThisTypes.ts, 0, 0)) +>Thing2 : Symbol(Thing2, Decl(intersectionThisTypes.ts, 3, 1)) + +type Thing4 = Thing3 & string[]; +>Thing4 : Symbol(Thing4, Decl(intersectionThisTypes.ts, 10, 30)) +>Thing3 : Symbol(Thing3, Decl(intersectionThisTypes.ts, 8, 1)) + +function f1(t: Thing3) { +>f1 : Symbol(f1, Decl(intersectionThisTypes.ts, 11, 32)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>Thing3 : Symbol(Thing3, Decl(intersectionThisTypes.ts, 8, 1)) + + t = t.self(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>t.self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) + + t = t.me().self().me(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>t.me().self().me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t.me().self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t.me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 13, 12)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +} + +interface Thing5 extends Thing4 { +>Thing5 : Symbol(Thing5, Decl(intersectionThisTypes.ts, 16, 1)) +>Thing4 : Symbol(Thing4, Decl(intersectionThisTypes.ts, 10, 30)) + + c: string; +>c : Symbol(Thing5.c, Decl(intersectionThisTypes.ts, 18, 33)) +} + +function f2(t: Thing5) { +>f2 : Symbol(f2, Decl(intersectionThisTypes.ts, 20, 1)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>Thing5 : Symbol(Thing5, Decl(intersectionThisTypes.ts, 16, 1)) + + t = t.self(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>t.self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) + + t = t.me().self().me(); +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>t.me().self().me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t.me().self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>t.me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>t : Symbol(t, Decl(intersectionThisTypes.ts, 22, 12)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +>self : Symbol(Thing1.self, Decl(intersectionThisTypes.ts, 1, 14)) +>me : Symbol(Thing2.me, Decl(intersectionThisTypes.ts, 6, 14)) +} + +interface Component { +>Component : Symbol(Component, Decl(intersectionThisTypes.ts, 25, 1)) + + extend(props: T): this & T; +>extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>T : Symbol(T, Decl(intersectionThisTypes.ts, 28, 11)) +>props : Symbol(props, Decl(intersectionThisTypes.ts, 28, 14)) +>T : Symbol(T, Decl(intersectionThisTypes.ts, 28, 11)) +>T : Symbol(T, Decl(intersectionThisTypes.ts, 28, 11)) +} + +interface Label extends Component { +>Label : Symbol(Label, Decl(intersectionThisTypes.ts, 29, 1)) +>Component : Symbol(Component, Decl(intersectionThisTypes.ts, 25, 1)) + + title: string; +>title : Symbol(Label.title, Decl(intersectionThisTypes.ts, 31, 35)) +} + +function test(label: Label) { +>test : Symbol(test, Decl(intersectionThisTypes.ts, 33, 1)) +>label : Symbol(label, Decl(intersectionThisTypes.ts, 35, 14)) +>Label : Symbol(Label, Decl(intersectionThisTypes.ts, 29, 1)) + + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); +>extended : Symbol(extended, Decl(intersectionThisTypes.ts, 36, 9)) +>label.extend({ id: 67 }).extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>label.extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>label : Symbol(label, Decl(intersectionThisTypes.ts, 35, 14)) +>extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>id : Symbol(id, Decl(intersectionThisTypes.ts, 36, 35)) +>extend : Symbol(Component.extend, Decl(intersectionThisTypes.ts, 27, 21)) +>tag : Symbol(tag, Decl(intersectionThisTypes.ts, 36, 54)) + + extended.id; // Ok +>extended.id : Symbol(id, Decl(intersectionThisTypes.ts, 36, 35)) +>extended : Symbol(extended, Decl(intersectionThisTypes.ts, 36, 9)) +>id : Symbol(id, Decl(intersectionThisTypes.ts, 36, 35)) + + extended.tag; // Ok +>extended.tag : Symbol(tag, Decl(intersectionThisTypes.ts, 36, 54)) +>extended : Symbol(extended, Decl(intersectionThisTypes.ts, 36, 9)) +>tag : Symbol(tag, Decl(intersectionThisTypes.ts, 36, 54)) +} + diff --git a/tests/baselines/reference/intersectionThisTypes.types b/tests/baselines/reference/intersectionThisTypes.types new file mode 100644 index 0000000000000..285609cdfdc21 --- /dev/null +++ b/tests/baselines/reference/intersectionThisTypes.types @@ -0,0 +1,145 @@ +=== tests/cases/conformance/types/intersection/intersectionThisTypes.ts === +interface Thing1 { +>Thing1 : Thing1 + + a: number; +>a : number + + self(): this; +>self : () => this +} + +interface Thing2 { +>Thing2 : Thing2 + + b: number; +>b : number + + me(): this; +>me : () => this +} + +type Thing3 = Thing1 & Thing2; +>Thing3 : Thing3 +>Thing1 : Thing1 +>Thing2 : Thing2 + +type Thing4 = Thing3 & string[]; +>Thing4 : Thing4 +>Thing3 : Thing3 + +function f1(t: Thing3) { +>f1 : (t: Thing3) => void +>t : Thing3 +>Thing3 : Thing3 + + t = t.self(); +>t = t.self() : Thing3 +>t : Thing3 +>t.self() : Thing3 +>t.self : () => Thing3 +>t : Thing3 +>self : () => Thing3 + + t = t.me().self().me(); +>t = t.me().self().me() : Thing3 +>t : Thing3 +>t.me().self().me() : Thing3 +>t.me().self().me : () => Thing3 +>t.me().self() : Thing3 +>t.me().self : () => Thing3 +>t.me() : Thing3 +>t.me : () => Thing3 +>t : Thing3 +>me : () => Thing3 +>self : () => Thing3 +>me : () => Thing3 +} + +interface Thing5 extends Thing4 { +>Thing5 : Thing5 +>Thing4 : Thing4 + + c: string; +>c : string +} + +function f2(t: Thing5) { +>f2 : (t: Thing5) => void +>t : Thing5 +>Thing5 : Thing5 + + t = t.self(); +>t = t.self() : Thing5 +>t : Thing5 +>t.self() : Thing5 +>t.self : () => Thing5 +>t : Thing5 +>self : () => Thing5 + + t = t.me().self().me(); +>t = t.me().self().me() : Thing5 +>t : Thing5 +>t.me().self().me() : Thing5 +>t.me().self().me : () => Thing5 +>t.me().self() : Thing5 +>t.me().self : () => Thing5 +>t.me() : Thing5 +>t.me : () => Thing5 +>t : Thing5 +>me : () => Thing5 +>self : () => Thing5 +>me : () => Thing5 +} + +interface Component { +>Component : Component + + extend(props: T): this & T; +>extend : (props: T) => this & T +>T : T +>props : T +>T : T +>T : T +} + +interface Label extends Component { +>Label : Label +>Component : Component + + title: string; +>title : string +} + +function test(label: Label) { +>test : (label: Label) => void +>label : Label +>Label : Label + + const extended = label.extend({ id: 67 }).extend({ tag: "hello" }); +>extended : Label & { id: number; } & { tag: string; } +>label.extend({ id: 67 }).extend({ tag: "hello" }) : Label & { id: number; } & { tag: string; } +>label.extend({ id: 67 }).extend : (props: T) => Label & { id: number; } & T +>label.extend({ id: 67 }) : Label & { id: number; } +>label.extend : (props: T) => Label & T +>label : Label +>extend : (props: T) => Label & T +>{ id: 67 } : { id: number; } +>id : number +>67 : 67 +>extend : (props: T) => Label & { id: number; } & T +>{ tag: "hello" } : { tag: string; } +>tag : string +>"hello" : "hello" + + extended.id; // Ok +>extended.id : number +>extended : Label & { id: number; } & { tag: string; } +>id : number + + extended.tag; // Ok +>extended.tag : string +>extended : Label & { id: number; } & { tag: string; } +>tag : string +} +