diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 7dd4ed1a39a2b..b7e0cee29867a 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -1409,6 +1409,7 @@ namespace ts { case SyntaxKind.ModuleDeclaration: case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.MappedType: + case SyntaxKind.TypeParameter: return ContainerFlags.IsContainer | ContainerFlags.HasLocals; case SyntaxKind.SourceFile: @@ -1530,6 +1531,7 @@ namespace ts { case SyntaxKind.JSDocCallbackTag: case SyntaxKind.TypeAliasDeclaration: case SyntaxKind.MappedType: + case SyntaxKind.TypeParameter: // All the children of these container types are never visible through another // symbol (i.e. through another symbol's 'exports' or 'members'). Instead, // they're only accessed 'lexically' (i.e. from code that exists underneath diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index fb1f62ddaf57c..3f3c44a2fb7f1 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5221,6 +5221,7 @@ namespace ts { case SyntaxKind.JSDocCallbackTag: case SyntaxKind.MappedType: case SyntaxKind.ConditionalType: + case SyntaxKind.TypeParameter: const outerTypeParameters = getOuterTypeParameters(node, includeThisTypes); if (node.kind === SyntaxKind.MappedType) { return append(outerTypeParameters, getDeclaredTypeOfTypeParameter(getSymbolOfNode((node).typeParameter))); @@ -5251,8 +5252,9 @@ namespace ts { if (node.kind === SyntaxKind.InterfaceDeclaration || node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || + node.kind === SyntaxKind.TypeParameter || isTypeAlias(node)) { - const declaration = node; + const declaration = node; result = appendTypeParameters(result, getEffectiveTypeParameterDeclarations(declaration)); } } @@ -5360,13 +5362,16 @@ namespace ts { if (type.objectFlags & ObjectFlags.Tuple) { type.resolvedBaseTypes = [createArrayType(getUnionType(type.typeParameters!))]; } - else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface)) { + else if (type.symbol.flags & (SymbolFlags.Class | SymbolFlags.Interface | SymbolFlags.TypeParameter)) { if (type.symbol.flags & SymbolFlags.Class) { resolveBaseTypesOfClass(type); } if (type.symbol.flags & SymbolFlags.Interface) { resolveBaseTypesOfInterface(type); } + if (type.symbol.flags & SymbolFlags.TypeParameter) { + resolveBaseTypesOfGenericTypeParameter(type); + } } else { Debug.fail("type must be class or interface"); @@ -5477,6 +5482,12 @@ namespace ts { } } + function resolveBaseTypesOfGenericTypeParameter(type: GenericTypeParameter): void { + type.resolvedBaseTypes = type.resolvedBaseTypes || emptyArray; + const constraint = getConstraintOfTypeParameter(type); + type.resolvedBaseTypes = constraint ? [constraint] : emptyArray; + } + /** * Returns true if the interface given by the symbol is free of "this" references. * @@ -5671,9 +5682,39 @@ namespace ts { function getDeclaredTypeOfTypeParameter(symbol: Symbol): TypeParameter { const links = getSymbolLinks(symbol); if (!links.declaredType) { - const type = createType(TypeFlags.TypeParameter); - type.symbol = symbol; - links.declaredType = type; + const localTypeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); + if (localTypeParameters) { + const type = createObjectType(ObjectFlags.GenericTypeParameter | ObjectFlags.Reference); + type.flags |= TypeFlags.TypeParameter; + type.symbol = symbol; + type.isGeneric = true; + links.declaredType = type; + + type.localTypeParameters = localTypeParameters; + const declaration = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter)!; + Debug.assertDefined(declaration); + // no point getting outerTypeParameters if there isn't a contraint since they can't be referenced without a constraint + const outerTypeParameters = declaration.constraint && getOuterTypeParameters(declaration); + type.outerTypeParameters = filter(outerTypeParameters, tp => tp !== type && isTypeParameterPossiblyReferenced(tp, declaration.constraint!)); + type.typeParameters = concatenate(type.outerTypeParameters, type.localTypeParameters); + + type.instantiations = createMap(); + type.instantiations.set(getTypeListId(type.typeParameters), type); + type.target = type; + type.typeArguments = type.typeParameters; + type.thisType = createType(TypeFlags.TypeParameter); + type.thisType.isThisType = true; + type.thisType.constraint = type; + type.declaredProperties = emptyArray; + type.declaredCallSignatures = emptyArray; + type.declaredConstructSignatures = emptyArray; + } + else { + const type = createType(TypeFlags.TypeParameter); + type.symbol = symbol; + links.declaredType = type; + type.isGeneric = false; + } } return links.declaredType; } @@ -6552,6 +6593,26 @@ namespace ts { return !!(getObjectFlags(type) & ObjectFlags.Mapped) && isGenericIndexType(getConstraintTypeFromMappedType(type)); } + function isTypeParameter(type: Type): type is TypeParameter { + return !!(type.flags & TypeFlags.TypeParameter); + } + + function isGenericTypeParameter(type: Type): type is GenericTypeParameter { + return isTypeParameter(type) && !!type.isGeneric; + } + + function isTypeParameterReference(type: Type): type is TypeReference { + return isTypeReference(type) && !!type.typeParameterReference; + } + + function isTypeVariable(type: Type): boolean { + return !!(type.flags & TypeFlags.TypeVariable || isTypeParameterReference(type)); + } + + function isTypeReference(type: Type): type is TypeReference { + return !!(getObjectFlags(type) & ObjectFlags.Reference); + } + function resolveStructuredTypeMembers(type: StructuredType): ResolvedType { if (!(type).members) { if (type.flags & TypeFlags.Object) { @@ -6844,11 +6905,21 @@ namespace ts { return type.resolvedApparentType || (type.resolvedApparentType = getTypeWithThisArgument(type, type, /*apparentType*/ true)); } + function getApparentTypeOfInstantiableType(type: InstantiableType) { + return isGenericTypeParameter(type) ? getApparentTypeOfGenericTypeParameter(type) : getBaseConstraintOfType(type); + } + + function getApparentTypeOfGenericTypeParameter(type: GenericTypeParameter) { + const localTypeArgs = map(type.localTypeParameters, getApparentType); + const outerTypeArgs = type.mapper && instantiateTypes(type.outerTypeParameters, type.mapper); + return createTypeReference(type, concatenate(outerTypeArgs, localTypeArgs)); + } + function getResolvedTypeParameterDefault(typeParameter: TypeParameter): Type | undefined { if (!typeParameter.default) { - if (typeParameter.target) { - const targetDefault = getResolvedTypeParameterDefault(typeParameter.target); - typeParameter.default = targetDefault ? instantiateType(targetDefault, typeParameter.mapper!) : noConstraintType; + if (typeParameter.original) { + const originalDefault = getResolvedTypeParameterDefault(typeParameter.original); + typeParameter.default = originalDefault ? instantiateType(originalDefault, typeParameter.mapper!) : noConstraintType; } else { // To block recursion, set the initial value to the resolvingDefaultType. @@ -6897,7 +6968,7 @@ namespace ts { * type itself. Note that the apparent type of a union type is the union type itself. */ function getApparentType(type: Type): Type { - const t = type.flags & TypeFlags.Instantiable ? getBaseConstraintOfType(type) || emptyObjectType : type; + const t = type.flags & TypeFlags.Instantiable ? getApparentTypeOfInstantiableType(type) || emptyObjectType : type; return t.flags & TypeFlags.Intersection ? getApparentTypeOfIntersectionType(t) : t.flags & TypeFlags.StringLike ? globalStringType : t.flags & TypeFlags.NumberLike ? globalNumberType : @@ -7544,15 +7615,17 @@ namespace ts { // that uses the original type identities for all unconstrained type parameters. return getSignatureInstantiation( signature, - map(signature.typeParameters, tp => tp.target && !getConstraintOfTypeParameter(tp.target) ? tp.target : tp), + map(signature.typeParameters, tp => tp.original && !getConstraintOfTypeParameter(tp.original) ? tp.original : tp), isInJavaScriptFile(signature.declaration)); } function getBaseSignature(signature: Signature) { const typeParameters = signature.typeParameters; if (typeParameters) { - const typeEraser = createTypeEraser(typeParameters); - const baseConstraints = map(typeParameters, tp => instantiateType(getBaseConstraintOfType(tp), typeEraser) || emptyObjectType); + // for generic type parameters just erase the child type parameters, not the generic type parameter itself + // because generic type parameters are an object type that can be inferred + const typeEraser = createTypeEraser(flatMap(typeParameters, tp => isGenericTypeParameter(tp) ? tp.localTypeParameters : tp)); + const baseConstraints = map(typeParameters, tp => instantiateType(getApparentTypeOfInstantiableType(tp), typeEraser) || emptyObjectType); return instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ true); } return signature; @@ -7654,9 +7727,9 @@ namespace ts { function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type | undefined { if (!typeParameter.constraint) { - if (typeParameter.target) { - const targetConstraint = getConstraintOfTypeParameter(typeParameter.target); - typeParameter.constraint = targetConstraint ? instantiateType(targetConstraint, typeParameter.mapper!) : noConstraintType; + if (typeParameter.original) { + const originalConstraint = getConstraintOfTypeParameter(typeParameter.original); + typeParameter.constraint = originalConstraint ? instantiateType(originalConstraint, typeParameter.mapper!) : noConstraintType; } else { const constraintDeclaration = getConstraintDeclaration(typeParameter); @@ -7718,6 +7791,7 @@ namespace ts { type.flags |= typeArguments ? getPropagatingFlagsOfTypes(typeArguments, /*excludeKinds*/ 0) : 0; type.target = target; type.typeArguments = typeArguments; + type.typeParameterReference = isGenericTypeParameter(target); } return type; } @@ -7742,6 +7816,10 @@ namespace ts { const type = getDeclaredTypeOfSymbol(getMergedSymbol(symbol)); const typeParameters = type.localTypeParameters; if (typeParameters) { + const genericTypeArgument = tryGetGenericTypeArgument(node, type); + if (genericTypeArgument) { + return genericTypeArgument; + } const numTypeArguments = length(node.typeArguments); const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); const isJs = isInJavaScriptFile(node); @@ -7809,6 +7887,48 @@ namespace ts { return checkNoTypeArguments(node, symbol) ? type : unknownType; } + function getTypeFromTypeParameterReference(node: NodeWithTypeArguments, symbol: Symbol, typeArguments: Type[] | undefined): Type { + const type = getDeclaredTypeOfSymbol(symbol); + if (isGenericTypeParameter(type)) { + const localTypeParameters = type.localTypeParameters; + const genericTypeArgument = tryGetGenericTypeArgument(node, type); + if (genericTypeArgument) { + return genericTypeArgument; + } + const minTypeArgs = getMinTypeArgumentCount(localTypeParameters); + if (length(typeArguments) < minTypeArgs || length(typeArguments) > length(localTypeParameters)) { + error(node, + minTypeArgs === localTypeParameters.length + ? Diagnostics.Generic_type_0_requires_1_type_argument_s + : Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, + symbolToString(symbol), + minTypeArgs, + localTypeParameters.length); + return unknownType; + } + const fullTypeArguments = concatenate(type.outerTypeParameters, fillMissingTypeArguments(typeArguments, localTypeParameters, minTypeArgs, isInJavaScriptFile(node))); + return createTypeReference(type, fullTypeArguments); + } + else if (!checkNoTypeArguments(node, symbol)) { + return unknownType; + } + return getConstrainedTypeVariable(type, node); + } + + function tryGetGenericTypeArgument(node: NodeWithTypeArguments, genericType: GenericType): Type | undefined { + Debug.assert(!!(getObjectFlags(genericType) & (ObjectFlags.ClassOrInterface | ObjectFlags.GenericTypeParameter) && genericType.target === genericType)); + const parentTypeParameter = tryGetParentGenericTypeParameter(node); + if (!parentTypeParameter || length(genericType.localTypeParameters) !== length(parentTypeParameter.localTypeParameters)) { + return undefined; + } + return makeGenericTypeArgument(parentTypeParameter, genericType); + } + + function makeGenericTypeArgument(source: GenericTypeParameter, target: GenericType): Type { + Debug.assertEqual(length(source.localTypeParameters), length(target.localTypeParameters)); + return createTypeReference(target, concatenate(target.outerTypeParameters, source.localTypeParameters)); + } + function getTypeReferenceName(node: TypeReferenceType): EntityNameOrEntityNameExpression | undefined { switch (node.kind) { case SyntaxKind.TypeReference: @@ -7902,6 +8022,10 @@ namespace ts { (symbol.members || getJSDocClassTag(symbol.valueDeclaration))) { return getInferredClassType(symbol); } + + if (symbol.flags & SymbolFlags.TypeParameter) { + return getTypeFromTypeParameterReference(node, symbol, typeArguments); + } } function getSubstitutionType(typeVariable: TypeVariable, substitute: Type) { @@ -9561,11 +9685,42 @@ namespace ts { return type.flags & TypeFlags.TypeParameter ? wildcardType : type; } - function cloneTypeParameter(typeParameter: TypeParameter): TypeParameter { - const result = createType(TypeFlags.TypeParameter); - result.symbol = typeParameter.symbol; - result.target = typeParameter; - return result; + function cloneTypeParameter(original: TypeParameter): TypeParameter { + if (isGenericTypeParameter(original)) { + const clone = createObjectType(ObjectFlags.GenericTypeParameter | ObjectFlags.Reference); + clone.flags |= TypeFlags.TypeParameter; + clone.symbol = original.symbol; + clone.isGeneric = original.isGeneric; + + // kpdonn: I currently haven't found it necessary to clone child type parameters but there may be edge cases I haven't found yet. + clone.localTypeParameters = original.localTypeParameters; + clone.outerTypeParameters = original.outerTypeParameters; + clone.typeParameters = original.typeParameters; + + clone.instantiations = createMap(); + clone.instantiations.set(getTypeListId(clone.typeParameters), clone); + clone.target = clone; + clone.typeArguments = clone.typeParameters; + + // TODO (kpdonn): figure out if this is needed and add test if so. + clone.thisType = createType(TypeFlags.TypeParameter); + clone.thisType.isThisType = true; + clone.thisType.constraint = clone; + + clone.declaredProperties = emptyArray; + clone.declaredCallSignatures = emptyArray; + clone.declaredConstructSignatures = emptyArray; + + clone.original = original; + return clone; + } + else { + const clone = createType(TypeFlags.TypeParameter); + clone.symbol = original.symbol; + clone.original = original; + clone.isGeneric = original.isGeneric; + return clone; + } } function instantiateTypePredicate(predicate: TypePredicate, mapper: TypeMapper): ThisTypePredicate | IdentifierTypePredicate { @@ -9701,9 +9856,9 @@ namespace ts { return type; } - function maybeTypeParameterReference(node: Node) { + function maybeTypeParameterReference(node: Node, genericTypeParameter: boolean) { return !(node.kind === SyntaxKind.QualifiedName || - node.parent.kind === SyntaxKind.TypeReference && (node.parent).typeArguments && node === (node.parent).typeName); + !genericTypeParameter && node.parent.kind === SyntaxKind.TypeReference && (node.parent).typeArguments && node === (node.parent).typeName); } function isTypeParameterPossiblyReferenced(tp: TypeParameter, node: Node) { @@ -9722,7 +9877,7 @@ namespace ts { case SyntaxKind.ThisType: return !!tp.isThisType; case SyntaxKind.Identifier: - return !tp.isThisType && isPartOfTypeNode(node) && maybeTypeParameterReference(node) && + return !tp.isThisType && isPartOfTypeNode(node) && maybeTypeParameterReference(node, !!tp.isGeneric) && getTypeFromTypeNode(node) === tp; case SyntaxKind.TypeQuery: return true; @@ -9804,6 +9959,12 @@ namespace ts { return getConditionalType(root, mapper); } + function instantiateTypeReference(type: TypeReference, mapper: TypeMapper): Type { + const typeArguments = type.typeArguments; + const newTypeArguments = instantiateTypes(typeArguments, mapper); + return newTypeArguments !== typeArguments ? createTypeReference(type.target, newTypeArguments) : type; + } + function instantiateType(type: Type, mapper: TypeMapper | undefined): Type; function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined; function instantiateType(type: Type | undefined, mapper: TypeMapper | undefined): Type | undefined { @@ -9822,10 +9983,18 @@ namespace ts { if ((type).objectFlags & ObjectFlags.Mapped) { return getAnonymousTypeInstantiation(type, mapper); } + if (isTypeParameterReference(type)) { + const newType = unwrapType(mapper(type.target)); + if (newType === type) { + return instantiateTypeReference(type, mapper); + } + const newMapper = combineTypeMappers(getLocalTypeArgumentMapper(type), mapper); + // if newType is genericTypeParameter it can't be instantiated by instantiateType because it would match + // type.flags & TypeFlags.TypeParameter before (type).objectFlags & ObjectFlags.Reference + return isGenericTypeParameter(newType) ? instantiateTypeReference(newType, newMapper) : instantiateType(newType, newMapper); + } if ((type).objectFlags & ObjectFlags.Reference) { - const typeArguments = (type).typeArguments; - const newTypeArguments = instantiateTypes(typeArguments, mapper); - return newTypeArguments !== typeArguments ? createTypeReference((type).target, newTypeArguments) : type; + return instantiateTypeReference(type, mapper); } } if (type.flags & TypeFlags.Union && !(type.flags & TypeFlags.Primitive)) { @@ -9854,6 +10023,14 @@ namespace ts { return type; } + function getLocalTypeArgumentMapper(type: TypeReference): TypeMapper | undefined { + if (length(type.target.localTypeParameters)) { + const localTypeArguments = type.typeArguments!.slice(length(type.target.outerTypeParameters), length(type.target.typeParameters)); + return createTypeMapper(type.target.localTypeParameters!, localTypeArguments); + } + return undefined; + } + function getWildcardInstantiation(type: Type) { return type.flags & (TypeFlags.Primitive | TypeFlags.Any | TypeFlags.Never) ? type : type.wildcardInstantiation || (type.wildcardInstantiation = instantiateType(type, wildcardMapper)); @@ -9979,6 +10156,7 @@ namespace ts { // T occurs directly or indirectly in an 'extends' clause of S. // Note that this check ignores type parameters and only considers the // inheritance hierarchy. + // TODO (kpdonn): determine what changes if any needed for generic type parameters function isTypeDerivedFrom(source: Type, target: Type): boolean { return source.flags & TypeFlags.Union ? every((source).types, t => isTypeDerivedFrom(t, target)) : target.flags & TypeFlags.Union ? some((target).types, t => isTypeDerivedFrom(source, t)) : @@ -12330,6 +12508,7 @@ namespace ts { function couldContainTypeVariables(type: Type): boolean { const objectFlags = getObjectFlags(type); return !!(type.flags & TypeFlags.Instantiable || + isTypeParameterReference(type) || objectFlags & ObjectFlags.Reference && forEach((type).typeArguments, couldContainTypeVariables) || objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.TypeLiteral | SymbolFlags.Class) || objectFlags & ObjectFlags.Mapped || @@ -12508,7 +12687,7 @@ namespace ts { target = removeTypesFromUnionOrIntersection(target, matchingTypes); } } - if (target.flags & TypeFlags.TypeVariable) { + if (isTypeVariable(target)) { // If target is a type parameter, make an inference, unless the source type contains // the anyFunctionType (the wildcard type that's used to avoid contextually typing functions). // Because the anyFunctionType is internal, it should not be exposed to the user by adding @@ -12540,7 +12719,9 @@ namespace ts { inference.topLevel = false; } } - return; + if (!isTypeParameterReference(target)) { + return; + } } } if (getObjectFlags(source) & ObjectFlags.Reference && getObjectFlags(target) & ObjectFlags.Reference && (source).target === (target).target) { @@ -12657,7 +12838,8 @@ namespace ts { } function getInferenceInfoForType(type: Type) { - if (type.flags & TypeFlags.TypeVariable) { + if (isTypeVariable(type)) { + type = isTypeParameterReference(type) ? type.target : type; for (const inference of inferences) { if (type === inference.typeParameter) { return inference; @@ -12883,9 +13065,22 @@ namespace ts { inferredType = getTypeFromInference(inference); } + let constraint = getConstraintOfTypeParameter(inference.typeParameter); + + if (isGenericTypeParameter(inference.typeParameter)) { + if (isTypeReference(inferredType) && length(inferredType.target.localTypeParameters) === length(inference.typeParameter.localTypeParameters)) { + inferredType = makeGenericTypeArgument(inference.typeParameter, inferredType.target); + } + + if (constraint && isTypeParameterReference(constraint) && !contains(context.typeParameters, getTargetType(constraint))) { + const genericArgument = wrapType(makeGenericTypeArgument(constraint.target, inference.typeParameter)); + const mapper = combineTypeMappers(makeUnaryTypeMapper(constraint.target, genericArgument), getLocalTypeArgumentMapper(constraint)); + constraint = instantiateType(getConstraintOfTypeParameter(constraint.target), mapper); + } + } + inference.inferredType = inferredType; - const constraint = getConstraintOfTypeParameter(inference.typeParameter); if (constraint) { const instantiatedConstraint = instantiateType(constraint, context); if (!context.compareTypes(inferredType, getTypeWithThisArgument(instantiatedConstraint, inferredType))) { @@ -12897,6 +13092,19 @@ namespace ts { return inferredType; } + function wrapType(type: Type): WrapperType { + if (!type.wrapperType) { + const wrapper = createObjectType(ObjectFlags.Wrapper); + wrapper.wrappedType = type; + type.wrapperType = wrapper; + } + return type.wrapperType; + } + + function unwrapType(type: Type): Type { + return getObjectFlags(type) & ObjectFlags.Wrapper ? (type).wrappedType : type; + } + function getDefaultTypeArgumentType(isInJavaScriptFile: boolean): Type { return isInJavaScriptFile ? anyType : emptyObjectType; } @@ -20901,6 +21109,7 @@ namespace ts { checkSourceElement(node.constraint); checkSourceElement(node.default); + checkTypeParameters(node.typeParameters); const typeParameter = getDeclaredTypeOfTypeParameter(getSymbolOfNode(node)); if (!hasNonCircularBaseConstraint(typeParameter)) { error(node.constraint, Diagnostics.Type_parameter_0_has_a_circular_constraint, typeToString(typeParameter)); @@ -21489,6 +21698,10 @@ namespace ts { typeArguments = getEffectiveTypeArguments(node, typeParameters); mapper = createTypeMapper(typeParameters, typeArguments); } + // TODO (kpdonn): handle generic type parameters + if (isGenericTypeParameter(typeParameters[i])) { + continue; + } result = result && checkTypeAssignableTo( typeArguments[i], instantiateType(constraint, mapper!), @@ -21542,6 +21755,21 @@ namespace ts { return constraint && instantiateType(constraint, createTypeMapper(typeParameters, getEffectiveTypeArguments(typeReferenceNode, typeParameters))); } + function tryGetParentGenericTypeParameter(node: NodeWithTypeArguments): GenericTypeParameter | undefined { + if (length(node.typeArguments) || !isTypeReferenceType(node.parent)) { + return undefined; + } + const name = getTypeReferenceName(node.parent); + const identifier = name && getFirstIdentifier(name); + const symbol = identifier && resolveEntityName(identifier, SymbolFlags.Type, /*ignoreErrors*/ true); + const typeParameters = symbol && getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); + if (!typeParameters) { + return undefined; + } + const typeParameter = typeParameters[node.parent.typeArguments!.indexOf(node)]; + return isGenericTypeParameter(typeParameter) ? typeParameter : undefined; + } + function checkTypeQuery(node: TypeQueryNode) { getTypeFromTypeQueryNode(node); } @@ -24205,6 +24433,7 @@ namespace ts { } } + // TODO (kpdonn): Update to handle type parameters with type parameters function areTypeParametersIdentical(declarations: ReadonlyArray, targetParameters: TypeParameter[]) { const maxTypeArgumentCount = length(targetParameters); const minTypeArgumentCount = getMinTypeArgumentCount(targetParameters); diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index cd89248144bb0..11c5200426f8c 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -79,6 +79,7 @@ namespace ts { visitNode(cbNode, (node).right); case SyntaxKind.TypeParameter: return visitNode(cbNode, (node).name) || + visitNodes(cbNode, cbNodes, (node).typeParameters) || visitNode(cbNode, (node).constraint) || visitNode(cbNode, (node).default) || visitNode(cbNode, (node).expression); @@ -1608,7 +1609,8 @@ namespace ts { return isVariableDeclaratorListTerminator(); case ParsingContext.TypeParameters: // Tokens other than '>' are here for better error recovery - return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword; + return token() === SyntaxKind.GreaterThanToken || token() === SyntaxKind.OpenParenToken || token() === SyntaxKind.OpenBraceToken || + token() === SyntaxKind.ExtendsKeyword || token() === SyntaxKind.ImplementsKeyword || token() === SyntaxKind.SemicolonToken; case ParsingContext.ArgumentExpressions: // Tokens other than ')' are here for better error recovery return token() === SyntaxKind.CloseParenToken || token() === SyntaxKind.SemicolonToken; @@ -2366,6 +2368,7 @@ namespace ts { function parseTypeParameter(): TypeParameterDeclaration { const node = createNode(SyntaxKind.TypeParameter); node.name = parseIdentifier(); + node.typeParameters = parseTypeParameters(); if (parseOptional(SyntaxKind.ExtendsKeyword)) { // It's not uncommon for people to write improper constraints to a generic. If the // user writes a constraint that is an expression and not an actual type, then parse diff --git a/src/compiler/types.ts b/src/compiler/types.ts index a3cdb32df0702..5e5eb847dd3d0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -802,6 +802,7 @@ namespace ts { kind: SyntaxKind.TypeParameter; parent: DeclarationWithTypeParameters | InferTypeNode; name: Identifier; + typeParameters?: NodeArray; constraint?: TypeNode; default?: TypeNode; @@ -2055,7 +2056,7 @@ namespace ts { export type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode; - export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; + export type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | TypeParameterDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; export interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer { kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression; @@ -3765,6 +3766,8 @@ namespace ts { aliasTypeArguments?: Type[]; // Alias type arguments (if any) /* @internal */ wildcardInstantiation?: Type; // Instantiation with type parameters mapped to wildcard type + /* @internal */ + wrapperType?: WrapperType; // wrapper type for this type } /* @internal */ @@ -3813,6 +3816,10 @@ namespace ts { ReverseMapped = 1 << 11, // Object contains a property from a reverse-mapped type JsxAttributes = 1 << 12, // Jsx attributes type MarkerType = 1 << 13, // Marker type used for variance probing + GenericTypeParameter = 1 << 14, // uninstantiated generic type parameter (meaning a type parameter that has its own type parameters) + /* @internal */ + Wrapper = 1 << 15, // wrapper for mapped GenericTypeParameters, which is needed to avoid instantiation order problems in some cases in getInferredType() + ClassOrInterface = Class | Interface } @@ -3855,8 +3862,9 @@ namespace ts { * explicit "this" argument. */ export interface TypeReference extends ObjectType { - target: GenericType; // Type reference target - typeArguments?: Type[]; // Type reference type arguments (undefined if none) + target: GenericType; // Type reference target + typeArguments?: Type[]; // Type reference type arguments (undefined if none) + typeParameterReference?: boolean; // true if target is a GenericTypeParameter but NOT true if this is the GenericTypeParameter (ie if this === target) } /* @internal */ @@ -3868,7 +3876,7 @@ namespace ts { Independent = 4, // Unwitnessed type parameter } - // Generic class and interface types + // Generic class, interface and type parameter types export interface GenericType extends InterfaceType, TypeReference { /* @internal */ instantiations: Map; // Generic instantiation cache @@ -3985,13 +3993,28 @@ namespace ts { /* @internal */ default?: Type; /* @internal */ - target?: TypeParameter; // Instantiation target + original?: TypeParameter; // The type parameter this type parameter was cloned from /* @internal */ - mapper?: TypeMapper; // Instantiation mapper + mapper?: TypeMapper; // mapper for cloned type parameters /* @internal */ isThisType?: boolean; /* @internal */ - resolvedDefaultType?: Type; + isGeneric?: boolean; + } + + // Generic type parameters (TypeFlags.TypeParameter, TypeFlags.Object, ObjectFlags.GenericTypeParameter) + export interface GenericTypeParameter extends GenericType, TypeParameter, InterfaceTypeWithDeclaredMembers { + localTypeParameters: TypeParameter[]; // GenericTypeParameters always have localTypeParameters since that's what distinguishes them from non-generic type parameters. + /* @internal */ + original?: GenericTypeParameter; // The type parameter this type parameter was cloned from + /* @internal */ + isGeneric: true; + } + + /* @internal */ + // ObjectFlags.Wrapper + export interface WrapperType extends ObjectType { + wrappedType: Type; } // Indexed access types (TypeFlags.IndexedAccess) diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index a3da44c5b1fea..0db6d06bacc21 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -541,6 +541,7 @@ namespace ts { case SyntaxKind.SetAccessor: case SyntaxKind.FunctionExpression: case SyntaxKind.ArrowFunction: + case SyntaxKind.TypeParameter: case SyntaxKind.JSDocCallbackTag: case SyntaxKind.JSDocTypedefTag: case SyntaxKind.JSDocSignature: diff --git a/src/services/completions.ts b/src/services/completions.ts index 56833298a644a..1fe1ec6fb68da 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -1776,6 +1776,7 @@ namespace ts.Completions { containingNodeKind === SyntaxKind.InterfaceDeclaration || // interface A; constraint?: TypeNode; default?: TypeNode; expression?: Expression; @@ -1282,7 +1283,7 @@ declare namespace ts { block: Block; } type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode; - type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; + type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | TypeParameterDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer { kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression; name?: Identifier; @@ -2210,6 +2211,7 @@ declare namespace ts { ReverseMapped = 2048, JsxAttributes = 4096, MarkerType = 8192, + GenericTypeParameter = 16384, ClassOrInterface = 3 } interface ObjectType extends Type { @@ -2243,6 +2245,7 @@ declare namespace ts { interface TypeReference extends ObjectType { target: GenericType; typeArguments?: Type[]; + typeParameterReference?: boolean; } interface GenericType extends InterfaceType, TypeReference { } @@ -2262,6 +2265,9 @@ declare namespace ts { } interface TypeParameter extends InstantiableType { } + interface GenericTypeParameter extends GenericType, TypeParameter, InterfaceTypeWithDeclaredMembers { + localTypeParameters: TypeParameter[]; + } interface IndexedAccessType extends InstantiableType { objectType: Type; indexType: Type; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 70f2e0d0cdbf5..af4b0960e7edd 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -532,6 +532,7 @@ declare namespace ts { kind: SyntaxKind.TypeParameter; parent: DeclarationWithTypeParameters | InferTypeNode; name: Identifier; + typeParameters?: NodeArray; constraint?: TypeNode; default?: TypeNode; expression?: Expression; @@ -1282,7 +1283,7 @@ declare namespace ts { block: Block; } type ObjectTypeDeclaration = ClassLikeDeclaration | InterfaceDeclaration | TypeLiteralNode; - type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; + type DeclarationWithTypeParameters = SignatureDeclaration | ClassLikeDeclaration | InterfaceDeclaration | TypeAliasDeclaration | TypeParameterDeclaration | JSDocTemplateTag | JSDocTypedefTag | JSDocCallbackTag | JSDocSignature; interface ClassLikeDeclarationBase extends NamedDeclaration, JSDocContainer { kind: SyntaxKind.ClassDeclaration | SyntaxKind.ClassExpression; name?: Identifier; @@ -2210,6 +2211,7 @@ declare namespace ts { ReverseMapped = 2048, JsxAttributes = 4096, MarkerType = 8192, + GenericTypeParameter = 16384, ClassOrInterface = 3 } interface ObjectType extends Type { @@ -2243,6 +2245,7 @@ declare namespace ts { interface TypeReference extends ObjectType { target: GenericType; typeArguments?: Type[]; + typeParameterReference?: boolean; } interface GenericType extends InterfaceType, TypeReference { } @@ -2262,6 +2265,9 @@ declare namespace ts { } interface TypeParameter extends InstantiableType { } + interface GenericTypeParameter extends GenericType, TypeParameter, InterfaceTypeWithDeclaredMembers { + localTypeParameters: TypeParameter[]; + } interface IndexedAccessType extends InstantiableType { objectType: Type; indexType: Type; diff --git a/tests/baselines/reference/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.js b/tests/baselines/reference/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.js new file mode 100644 index 0000000000000..0c3178b436967 --- /dev/null +++ b/tests/baselines/reference/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.js @@ -0,0 +1,55 @@ +//// [getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts] +export declare function f1(cb: (x: S) => T): T; +export declare function f2(cb: (x: S) => T): T; +export declare function f3(cb: (x: S) => T): T; +export declare function f4(cb: (x: S) => T): T; +export declare function f5(cb: (x: S) => T, obj: O): keyof O; +export declare function f6(cb: (x: S) => T, obj: O): T; +export declare function f7(cb: >(x: S) => T, obj: O): T; + +const x1 = f1(x => x); +const expectedx1: number = x1; + +let x2 = f2(x => x); +const expectedx2: string = x2; + +let x3 = f3(x => x); +const expectedx3: symbol = x3; + +let x4 = f4(x => x); +const expectedx4: number | string | symbol = x4; + +declare const symProp: unique symbol +declare const obj: { + prop: string, + [symProp]: symbol, + [index: number]: number +} + + +let x5 = f5((x) => x, obj); +const expectedx5: number | string | symbol = x5; + +let x6 = f6(x => x, obj); +const expectedx6: string = x6; + +let x7 = f7(x => x, obj); +const expectedx7: string = x7; + +//// [getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.js] +"use strict"; +exports.__esModule = true; +var x1 = f1(function (x) { return x; }); +var expectedx1 = x1; +var x2 = f2(function (x) { return x; }); +var expectedx2 = x2; +var x3 = f3(function (x) { return x; }); +var expectedx3 = x3; +var x4 = f4(function (x) { return x; }); +var expectedx4 = x4; +var x5 = f5(function (x) { return x; }, obj); +var expectedx5 = x5; +var x6 = f6(function (x) { return x; }, obj); +var expectedx6 = x6; +var x7 = f7(function (x) { return x; }, obj); +var expectedx7 = x7; diff --git a/tests/baselines/reference/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.symbols b/tests/baselines/reference/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.symbols new file mode 100644 index 0000000000000..8c546194aee3f --- /dev/null +++ b/tests/baselines/reference/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.symbols @@ -0,0 +1,175 @@ +=== tests/cases/compiler/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts === +export declare function f1(cb: (x: S) => T): T; +>f1 : Symbol(f1, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 0)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 27)) +>cb : Symbol(cb, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 30)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 35)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 53)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 35)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 27)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 27)) + +export declare function f2(cb: (x: S) => T): T; +>f2 : Symbol(f2, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 68)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 1, 27)) +>cb : Symbol(cb, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 1, 30)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 1, 35)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 1, 53)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 1, 35)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 1, 27)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 1, 27)) + +export declare function f3(cb: (x: S) => T): T; +>f3 : Symbol(f3, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 1, 68)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 2, 27)) +>cb : Symbol(cb, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 2, 30)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 2, 35)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 2, 53)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 2, 35)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 2, 27)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 2, 27)) + +export declare function f4(cb: (x: S) => T): T; +>f4 : Symbol(f4, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 2, 68)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 3, 27)) +>cb : Symbol(cb, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 3, 30)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 3, 35)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 3, 71)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 3, 35)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 3, 27)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 3, 27)) + +export declare function f5(cb: (x: S) => T, obj: O): keyof O; +>f5 : Symbol(f5, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 3, 86)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 27)) +>O : Symbol(O, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 29)) +>cb : Symbol(cb, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 33)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 38)) +>O : Symbol(O, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 29)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 57)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 38)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 27)) +>obj : Symbol(obj, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 68)) +>O : Symbol(O, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 29)) +>O : Symbol(O, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 29)) + +export declare function f6(cb: (x: S) => T, obj: O): T; +>f6 : Symbol(f6, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 86)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 27)) +>O : Symbol(O, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 29)) +>cb : Symbol(cb, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 33)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 38)) +>O : Symbol(O, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 29)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 66)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 38)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 27)) +>obj : Symbol(obj, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 77)) +>O : Symbol(O, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 29)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 27)) + +export declare function f7(cb: >(x: S) => T, obj: O): T; +>f7 : Symbol(f7, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 89)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 27)) +>O : Symbol(O, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 29)) +>cb : Symbol(cb, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 33)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 38)) +>Extract : Symbol(Extract, Decl(lib.d.ts, --, --)) +>O : Symbol(O, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 29)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 74)) +>S : Symbol(S, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 38)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 27)) +>obj : Symbol(obj, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 85)) +>O : Symbol(O, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 29)) +>T : Symbol(T, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 6, 27)) + +const x1 = f1(x => x); +>x1 : Symbol(x1, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 8, 5)) +>f1 : Symbol(f1, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 0)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 8, 14)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 8, 14)) + +const expectedx1: number = x1; +>expectedx1 : Symbol(expectedx1, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 9, 5)) +>x1 : Symbol(x1, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 8, 5)) + +let x2 = f2(x => x); +>x2 : Symbol(x2, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 11, 3)) +>f2 : Symbol(f2, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 0, 68)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 11, 12)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 11, 12)) + +const expectedx2: string = x2; +>expectedx2 : Symbol(expectedx2, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 12, 5)) +>x2 : Symbol(x2, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 11, 3)) + +let x3 = f3(x => x); +>x3 : Symbol(x3, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 14, 3)) +>f3 : Symbol(f3, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 1, 68)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 14, 12)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 14, 12)) + +const expectedx3: symbol = x3; +>expectedx3 : Symbol(expectedx3, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 15, 5)) +>x3 : Symbol(x3, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 14, 3)) + +let x4 = f4(x => x); +>x4 : Symbol(x4, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 17, 3)) +>f4 : Symbol(f4, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 2, 68)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 17, 12)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 17, 12)) + +const expectedx4: number | string | symbol = x4; +>expectedx4 : Symbol(expectedx4, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 18, 5)) +>x4 : Symbol(x4, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 17, 3)) + +declare const symProp: unique symbol +>symProp : Symbol(symProp, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 20, 13)) + +declare const obj: { +>obj : Symbol(obj, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 21, 13)) + + prop: string, +>prop : Symbol(prop, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 21, 20)) + + [symProp]: symbol, +>[symProp] : Symbol([symProp], Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 22, 17)) +>symProp : Symbol(symProp, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 20, 13)) + + [index: number]: number +>index : Symbol(index, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 24, 5)) +} + + +let x5 = f5((x) => x, obj); +>x5 : Symbol(x5, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 28, 3)) +>f5 : Symbol(f5, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 3, 86)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 28, 13)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 28, 13)) +>obj : Symbol(obj, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 21, 13)) + +const expectedx5: number | string | symbol = x5; +>expectedx5 : Symbol(expectedx5, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 29, 5)) +>x5 : Symbol(x5, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 28, 3)) + +let x6 = f6(x => x, obj); +>x6 : Symbol(x6, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 31, 3)) +>f6 : Symbol(f6, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 4, 86)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 31, 12)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 31, 12)) +>obj : Symbol(obj, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 21, 13)) + +const expectedx6: string = x6; +>expectedx6 : Symbol(expectedx6, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 32, 5)) +>x6 : Symbol(x6, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 31, 3)) + +let x7 = f7(x => x, obj); +>x7 : Symbol(x7, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 34, 3)) +>f7 : Symbol(f7, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 5, 89)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 34, 12)) +>x : Symbol(x, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 34, 12)) +>obj : Symbol(obj, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 21, 13)) + +const expectedx7: string = x7; +>expectedx7 : Symbol(expectedx7, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 35, 5)) +>x7 : Symbol(x7, Decl(getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts, 34, 3)) + diff --git a/tests/baselines/reference/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.types b/tests/baselines/reference/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.types new file mode 100644 index 0000000000000..86966a1c2bc29 --- /dev/null +++ b/tests/baselines/reference/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.types @@ -0,0 +1,189 @@ +=== tests/cases/compiler/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts === +export declare function f1(cb: (x: S) => T): T; +>f1 : (cb: (x: S) => T) => T +>T : T +>cb : (x: S) => T +>S : S +>x : S +>S : S +>T : T +>T : T + +export declare function f2(cb: (x: S) => T): T; +>f2 : (cb: (x: S) => T) => T +>T : T +>cb : (x: S) => T +>S : S +>x : S +>S : S +>T : T +>T : T + +export declare function f3(cb: (x: S) => T): T; +>f3 : (cb: (x: S) => T) => T +>T : T +>cb : (x: S) => T +>S : S +>x : S +>S : S +>T : T +>T : T + +export declare function f4(cb: (x: S) => T): T; +>f4 : (cb: (x: S) => T) => T +>T : T +>cb : (x: S) => T +>S : S +>x : S +>S : S +>T : T +>T : T + +export declare function f5(cb: (x: S) => T, obj: O): keyof O; +>f5 : (cb: (x: S) => T, obj: O) => keyof O +>T : T +>O : O +>cb : (x: S) => T +>S : S +>O : O +>x : S +>S : S +>T : T +>obj : O +>O : O +>O : O + +export declare function f6(cb: (x: S) => T, obj: O): T; +>f6 : (cb: (x: S) => T, obj: O) => T +>T : T +>O : O +>cb : (x: S) => T +>S : S +>O : O +>x : S +>S : S +>T : T +>obj : O +>O : O +>T : T + +export declare function f7(cb: >(x: S) => T, obj: O): T; +>f7 : (cb: >(x: S) => T, obj: O) => T +>T : T +>O : O +>cb : >(x: S) => T +>S : S +>Extract : Extract +>O : O +>x : S +>S : S +>T : T +>obj : O +>O : O +>T : T + +const x1 = f1(x => x); +>x1 : number +>f1(x => x) : number +>f1 : (cb: (x: S) => T) => T +>x => x : (x: S) => S +>x : S +>x : S + +const expectedx1: number = x1; +>expectedx1 : number +>x1 : number + +let x2 = f2(x => x); +>x2 : string +>f2(x => x) : string +>f2 : (cb: (x: S) => T) => T +>x => x : (x: S) => S +>x : S +>x : S + +const expectedx2: string = x2; +>expectedx2 : string +>x2 : string + +let x3 = f3(x => x); +>x3 : symbol +>f3(x => x) : symbol +>f3 : (cb: (x: S) => T) => T +>x => x : (x: S) => S +>x : S +>x : S + +const expectedx3: symbol = x3; +>expectedx3 : symbol +>x3 : symbol + +let x4 = f4(x => x); +>x4 : string | number | symbol +>f4(x => x) : string | number | symbol +>f4 : (cb: (x: S) => T) => T +>x => x : (x: S) => S +>x : S +>x : S + +const expectedx4: number | string | symbol = x4; +>expectedx4 : string | number | symbol +>x4 : string | number | symbol + +declare const symProp: unique symbol +>symProp : unique symbol + +declare const obj: { +>obj : { [index: number]: number; prop: string; [symProp]: symbol; } + + prop: string, +>prop : string + + [symProp]: symbol, +>[symProp] : symbol +>symProp : unique symbol + + [index: number]: number +>index : number +} + + +let x5 = f5((x) => x, obj); +>x5 : number | unique symbol | "prop" +>f5((x) => x, obj) : number | unique symbol | "prop" +>f5 : (cb: (x: S) => T, obj: O) => keyof O +>(x) => x : (x: S) => S +>x : S +>x : S +>obj : { [index: number]: number; prop: string; [symProp]: symbol; } + +const expectedx5: number | string | symbol = x5; +>expectedx5 : string | number | symbol +>x5 : number | unique symbol | "prop" + +let x6 = f6(x => x, obj); +>x6 : "prop" +>f6(x => x, obj) : "prop" +>f6 : (cb: (x: S) => T, obj: O) => T +>x => x : (x: S) => S +>x : S +>x : S +>obj : { [index: number]: number; prop: string; [symProp]: symbol; } + +const expectedx6: string = x6; +>expectedx6 : string +>x6 : "prop" + +let x7 = f7(x => x, obj); +>x7 : "prop" +>f7(x => x, obj) : "prop" +>f7 : (cb: >(x: S) => T, obj: O) => T +>x => x : (x: S) => S +>x : S +>x : S +>obj : { [index: number]: number; prop: string; [symProp]: symbol; } + +const expectedx7: string = x7; +>expectedx7 : string +>x7 : "prop" + diff --git a/tests/baselines/reference/higherKindedTypes.errors.txt b/tests/baselines/reference/higherKindedTypes.errors.txt new file mode 100644 index 0000000000000..cd7d77b14ba17 --- /dev/null +++ b/tests/baselines/reference/higherKindedTypes.errors.txt @@ -0,0 +1,68 @@ +tests/cases/compiler/higherKindedTypes.ts(37,5): error TS2322: Type 'F' is not assignable to type 'F'. + Type 'A' is not assignable to type 'B'. +tests/cases/compiler/higherKindedTypes.ts(42,23): error TS2339: Property 'map' does not exist on type 'F'. + + +==== tests/cases/compiler/higherKindedTypes.ts (2 errors) ==== + interface Functor> { + map(f: (a: A) => B): Container; + } + + interface FunctorX extends Functor { + map(f: (a: A) => B): FunctorX; + xVal: string; + } + + interface FunctorY extends Functor { + map(f: (a: A) => B): FunctorY; + yVal: A; + } + + declare const initialX: FunctorX; + declare const initialY: FunctorY; + + const resultX1 = initialX.map(val => val.length); + const expectX1: FunctorX = resultX1; + + const resultY1 = initialY.map(val => val.length); + const expectY1: FunctorY = resultY1; + + const resultX2 = initialX.map(val => [val]); + const expectX2: FunctorX = resultX2; + + const resultY2 = initialY.map(val => [val]); + const expectY2: FunctorY = resultY2; + + + function staticMap extends Functor<_T, F>, A, B>(fa: F, f: (a: A) => B): F { + const result = fa.map(f); + return result; + } + + function staticMapBadImplementation extends Functor<_T, F>, A, B>(fa: F, f: (a: A) => B): F { + return fa; + ~~~~~~~~~~ +!!! error TS2322: Type 'F' is not assignable to type 'F'. +!!! error TS2322: Type 'A' is not assignable to type 'B'. + } + + function staticMapNoConstraint, A, B>(fa: F, f: (a: A) => B): F { + // expect error here since F has no constraint so we have no idea what shape it will be + const result = fa.map(f); + ~~~ +!!! error TS2339: Property 'map' does not exist on type 'F'. + return result; + } + + const resultX3 = staticMap(initialX, val => val.length); + const expectX3: FunctorX = resultX3; + + const resultY3 = staticMap(initialY, val => val.length); + const expectY3: FunctorY = resultY3; + + const resultX4 = staticMap(initialX, val => [val]); + const expectX4: FunctorX = resultX4; + + const resultY4 = staticMap(initialY, val => [val]); + const expectY4: FunctorY = resultY4; + \ No newline at end of file diff --git a/tests/baselines/reference/higherKindedTypes.js b/tests/baselines/reference/higherKindedTypes.js new file mode 100644 index 0000000000000..03ec38f336e57 --- /dev/null +++ b/tests/baselines/reference/higherKindedTypes.js @@ -0,0 +1,89 @@ +//// [higherKindedTypes.ts] +interface Functor> { + map(f: (a: A) => B): Container; +} + +interface FunctorX extends Functor { + map(f: (a: A) => B): FunctorX; + xVal: string; +} + +interface FunctorY extends Functor { + map(f: (a: A) => B): FunctorY; + yVal: A; +} + +declare const initialX: FunctorX; +declare const initialY: FunctorY; + +const resultX1 = initialX.map(val => val.length); +const expectX1: FunctorX = resultX1; + +const resultY1 = initialY.map(val => val.length); +const expectY1: FunctorY = resultY1; + +const resultX2 = initialX.map(val => [val]); +const expectX2: FunctorX = resultX2; + +const resultY2 = initialY.map(val => [val]); +const expectY2: FunctorY = resultY2; + + +function staticMap extends Functor<_T, F>, A, B>(fa: F, f: (a: A) => B): F { + const result = fa.map(f); + return result; +} + +function staticMapBadImplementation extends Functor<_T, F>, A, B>(fa: F, f: (a: A) => B): F { + return fa; +} + +function staticMapNoConstraint, A, B>(fa: F, f: (a: A) => B): F { + // expect error here since F has no constraint so we have no idea what shape it will be + const result = fa.map(f); + return result; +} + +const resultX3 = staticMap(initialX, val => val.length); +const expectX3: FunctorX = resultX3; + +const resultY3 = staticMap(initialY, val => val.length); +const expectY3: FunctorY = resultY3; + +const resultX4 = staticMap(initialX, val => [val]); +const expectX4: FunctorX = resultX4; + +const resultY4 = staticMap(initialY, val => [val]); +const expectY4: FunctorY = resultY4; + + +//// [higherKindedTypes.js] +"use strict"; +var resultX1 = initialX.map(function (val) { return val.length; }); +var expectX1 = resultX1; +var resultY1 = initialY.map(function (val) { return val.length; }); +var expectY1 = resultY1; +var resultX2 = initialX.map(function (val) { return [val]; }); +var expectX2 = resultX2; +var resultY2 = initialY.map(function (val) { return [val]; }); +var expectY2 = resultY2; +function staticMap(fa, f) { + var result = fa.map(f); + return result; +} +function staticMapBadImplementation(fa, f) { + return fa; +} +function staticMapNoConstraint(fa, f) { + // expect error here since F has no constraint so we have no idea what shape it will be + var result = fa.map(f); + return result; +} +var resultX3 = staticMap(initialX, function (val) { return val.length; }); +var expectX3 = resultX3; +var resultY3 = staticMap(initialY, function (val) { return val.length; }); +var expectY3 = resultY3; +var resultX4 = staticMap(initialX, function (val) { return [val]; }); +var expectX4 = resultX4; +var resultY4 = staticMap(initialY, function (val) { return [val]; }); +var expectY4 = resultY4; diff --git a/tests/baselines/reference/higherKindedTypes.symbols b/tests/baselines/reference/higherKindedTypes.symbols new file mode 100644 index 0000000000000..7fb99ad2e14b3 --- /dev/null +++ b/tests/baselines/reference/higherKindedTypes.symbols @@ -0,0 +1,257 @@ +=== tests/cases/compiler/higherKindedTypes.ts === +interface Functor> { +>Functor : Symbol(Functor, Decl(higherKindedTypes.ts, 0, 0)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 0, 18)) +>Container : Symbol(Container, Decl(higherKindedTypes.ts, 0, 20)) +>_T : Symbol(_T, Decl(higherKindedTypes.ts, 0, 31)) + + map(f: (a: A) => B): Container; +>map : Symbol(Functor.map, Decl(higherKindedTypes.ts, 0, 37)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 1, 8)) +>f : Symbol(f, Decl(higherKindedTypes.ts, 1, 11)) +>a : Symbol(a, Decl(higherKindedTypes.ts, 1, 15)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 0, 18)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 1, 8)) +>Container : Symbol(Container, Decl(higherKindedTypes.ts, 0, 20)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 1, 8)) +} + +interface FunctorX extends Functor { +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypes.ts, 2, 1)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 4, 19)) +>Functor : Symbol(Functor, Decl(higherKindedTypes.ts, 0, 0)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 4, 19)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypes.ts, 2, 1)) + + map(f: (a: A) => B): FunctorX; +>map : Symbol(FunctorX.map, Decl(higherKindedTypes.ts, 4, 52)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 5, 8)) +>f : Symbol(f, Decl(higherKindedTypes.ts, 5, 11)) +>a : Symbol(a, Decl(higherKindedTypes.ts, 5, 15)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 4, 19)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 5, 8)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypes.ts, 2, 1)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 5, 8)) + + xVal: string; +>xVal : Symbol(FunctorX.xVal, Decl(higherKindedTypes.ts, 5, 40)) +} + +interface FunctorY extends Functor { +>FunctorY : Symbol(FunctorY, Decl(higherKindedTypes.ts, 7, 1)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 9, 19)) +>Functor : Symbol(Functor, Decl(higherKindedTypes.ts, 0, 0)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 9, 19)) +>FunctorY : Symbol(FunctorY, Decl(higherKindedTypes.ts, 7, 1)) + + map(f: (a: A) => B): FunctorY; +>map : Symbol(FunctorY.map, Decl(higherKindedTypes.ts, 9, 52)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 10, 8)) +>f : Symbol(f, Decl(higherKindedTypes.ts, 10, 11)) +>a : Symbol(a, Decl(higherKindedTypes.ts, 10, 15)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 9, 19)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 10, 8)) +>FunctorY : Symbol(FunctorY, Decl(higherKindedTypes.ts, 7, 1)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 10, 8)) + + yVal: A; +>yVal : Symbol(FunctorY.yVal, Decl(higherKindedTypes.ts, 10, 40)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 9, 19)) +} + +declare const initialX: FunctorX; +>initialX : Symbol(initialX, Decl(higherKindedTypes.ts, 14, 13)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypes.ts, 2, 1)) + +declare const initialY: FunctorY; +>initialY : Symbol(initialY, Decl(higherKindedTypes.ts, 15, 13)) +>FunctorY : Symbol(FunctorY, Decl(higherKindedTypes.ts, 7, 1)) + +const resultX1 = initialX.map(val => val.length); +>resultX1 : Symbol(resultX1, Decl(higherKindedTypes.ts, 17, 5)) +>initialX.map : Symbol(FunctorX.map, Decl(higherKindedTypes.ts, 4, 52)) +>initialX : Symbol(initialX, Decl(higherKindedTypes.ts, 14, 13)) +>map : Symbol(FunctorX.map, Decl(higherKindedTypes.ts, 4, 52)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 17, 30)) +>val.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 17, 30)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + +const expectX1: FunctorX = resultX1; +>expectX1 : Symbol(expectX1, Decl(higherKindedTypes.ts, 18, 5)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypes.ts, 2, 1)) +>resultX1 : Symbol(resultX1, Decl(higherKindedTypes.ts, 17, 5)) + +const resultY1 = initialY.map(val => val.length); +>resultY1 : Symbol(resultY1, Decl(higherKindedTypes.ts, 20, 5)) +>initialY.map : Symbol(FunctorY.map, Decl(higherKindedTypes.ts, 9, 52)) +>initialY : Symbol(initialY, Decl(higherKindedTypes.ts, 15, 13)) +>map : Symbol(FunctorY.map, Decl(higherKindedTypes.ts, 9, 52)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 20, 30)) +>val.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 20, 30)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + +const expectY1: FunctorY = resultY1; +>expectY1 : Symbol(expectY1, Decl(higherKindedTypes.ts, 21, 5)) +>FunctorY : Symbol(FunctorY, Decl(higherKindedTypes.ts, 7, 1)) +>resultY1 : Symbol(resultY1, Decl(higherKindedTypes.ts, 20, 5)) + +const resultX2 = initialX.map(val => [val]); +>resultX2 : Symbol(resultX2, Decl(higherKindedTypes.ts, 23, 5)) +>initialX.map : Symbol(FunctorX.map, Decl(higherKindedTypes.ts, 4, 52)) +>initialX : Symbol(initialX, Decl(higherKindedTypes.ts, 14, 13)) +>map : Symbol(FunctorX.map, Decl(higherKindedTypes.ts, 4, 52)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 23, 30)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 23, 30)) + +const expectX2: FunctorX = resultX2; +>expectX2 : Symbol(expectX2, Decl(higherKindedTypes.ts, 24, 5)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypes.ts, 2, 1)) +>resultX2 : Symbol(resultX2, Decl(higherKindedTypes.ts, 23, 5)) + +const resultY2 = initialY.map(val => [val]); +>resultY2 : Symbol(resultY2, Decl(higherKindedTypes.ts, 26, 5)) +>initialY.map : Symbol(FunctorY.map, Decl(higherKindedTypes.ts, 9, 52)) +>initialY : Symbol(initialY, Decl(higherKindedTypes.ts, 15, 13)) +>map : Symbol(FunctorY.map, Decl(higherKindedTypes.ts, 9, 52)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 26, 30)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 26, 30)) + +const expectY2: FunctorY = resultY2; +>expectY2 : Symbol(expectY2, Decl(higherKindedTypes.ts, 27, 5)) +>FunctorY : Symbol(FunctorY, Decl(higherKindedTypes.ts, 7, 1)) +>resultY2 : Symbol(resultY2, Decl(higherKindedTypes.ts, 26, 5)) + + +function staticMap extends Functor<_T, F>, A, B>(fa: F, f: (a: A) => B): F { +>staticMap : Symbol(staticMap, Decl(higherKindedTypes.ts, 27, 46)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 30, 19)) +>_T : Symbol(_T, Decl(higherKindedTypes.ts, 30, 21)) +>Functor : Symbol(Functor, Decl(higherKindedTypes.ts, 0, 0)) +>_T : Symbol(_T, Decl(higherKindedTypes.ts, 30, 21)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 30, 19)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 30, 48)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 30, 51)) +>fa : Symbol(fa, Decl(higherKindedTypes.ts, 30, 55)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 30, 19)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 30, 48)) +>f : Symbol(f, Decl(higherKindedTypes.ts, 30, 64)) +>a : Symbol(a, Decl(higherKindedTypes.ts, 30, 69)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 30, 48)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 30, 51)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 30, 19)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 30, 51)) + + const result = fa.map(f); +>result : Symbol(result, Decl(higherKindedTypes.ts, 31, 9)) +>fa.map : Symbol(Functor.map, Decl(higherKindedTypes.ts, 0, 37)) +>fa : Symbol(fa, Decl(higherKindedTypes.ts, 30, 55)) +>map : Symbol(Functor.map, Decl(higherKindedTypes.ts, 0, 37)) +>f : Symbol(f, Decl(higherKindedTypes.ts, 30, 64)) + + return result; +>result : Symbol(result, Decl(higherKindedTypes.ts, 31, 9)) +} + +function staticMapBadImplementation extends Functor<_T, F>, A, B>(fa: F, f: (a: A) => B): F { +>staticMapBadImplementation : Symbol(staticMapBadImplementation, Decl(higherKindedTypes.ts, 33, 1)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 35, 36)) +>_T : Symbol(_T, Decl(higherKindedTypes.ts, 35, 38)) +>Functor : Symbol(Functor, Decl(higherKindedTypes.ts, 0, 0)) +>_T : Symbol(_T, Decl(higherKindedTypes.ts, 35, 38)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 35, 36)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 35, 65)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 35, 68)) +>fa : Symbol(fa, Decl(higherKindedTypes.ts, 35, 72)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 35, 36)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 35, 65)) +>f : Symbol(f, Decl(higherKindedTypes.ts, 35, 81)) +>a : Symbol(a, Decl(higherKindedTypes.ts, 35, 86)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 35, 65)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 35, 68)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 35, 36)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 35, 68)) + + return fa; +>fa : Symbol(fa, Decl(higherKindedTypes.ts, 35, 72)) +} + +function staticMapNoConstraint, A, B>(fa: F, f: (a: A) => B): F { +>staticMapNoConstraint : Symbol(staticMapNoConstraint, Decl(higherKindedTypes.ts, 37, 1)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 39, 31)) +>_T : Symbol(_T, Decl(higherKindedTypes.ts, 39, 33)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 39, 37)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 39, 40)) +>fa : Symbol(fa, Decl(higherKindedTypes.ts, 39, 44)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 39, 31)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 39, 37)) +>f : Symbol(f, Decl(higherKindedTypes.ts, 39, 53)) +>a : Symbol(a, Decl(higherKindedTypes.ts, 39, 58)) +>A : Symbol(A, Decl(higherKindedTypes.ts, 39, 37)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 39, 40)) +>F : Symbol(F, Decl(higherKindedTypes.ts, 39, 31)) +>B : Symbol(B, Decl(higherKindedTypes.ts, 39, 40)) + + // expect error here since F has no constraint so we have no idea what shape it will be + const result = fa.map(f); +>result : Symbol(result, Decl(higherKindedTypes.ts, 41, 9)) +>fa : Symbol(fa, Decl(higherKindedTypes.ts, 39, 44)) +>f : Symbol(f, Decl(higherKindedTypes.ts, 39, 53)) + + return result; +>result : Symbol(result, Decl(higherKindedTypes.ts, 41, 9)) +} + +const resultX3 = staticMap(initialX, val => val.length); +>resultX3 : Symbol(resultX3, Decl(higherKindedTypes.ts, 45, 5)) +>staticMap : Symbol(staticMap, Decl(higherKindedTypes.ts, 27, 46)) +>initialX : Symbol(initialX, Decl(higherKindedTypes.ts, 14, 13)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 45, 36)) +>val.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 45, 36)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + +const expectX3: FunctorX = resultX3; +>expectX3 : Symbol(expectX3, Decl(higherKindedTypes.ts, 46, 5)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypes.ts, 2, 1)) +>resultX3 : Symbol(resultX3, Decl(higherKindedTypes.ts, 45, 5)) + +const resultY3 = staticMap(initialY, val => val.length); +>resultY3 : Symbol(resultY3, Decl(higherKindedTypes.ts, 48, 5)) +>staticMap : Symbol(staticMap, Decl(higherKindedTypes.ts, 27, 46)) +>initialY : Symbol(initialY, Decl(higherKindedTypes.ts, 15, 13)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 48, 36)) +>val.length : Symbol(String.length, Decl(lib.d.ts, --, --)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 48, 36)) +>length : Symbol(String.length, Decl(lib.d.ts, --, --)) + +const expectY3: FunctorY = resultY3; +>expectY3 : Symbol(expectY3, Decl(higherKindedTypes.ts, 49, 5)) +>FunctorY : Symbol(FunctorY, Decl(higherKindedTypes.ts, 7, 1)) +>resultY3 : Symbol(resultY3, Decl(higherKindedTypes.ts, 48, 5)) + +const resultX4 = staticMap(initialX, val => [val]); +>resultX4 : Symbol(resultX4, Decl(higherKindedTypes.ts, 51, 5)) +>staticMap : Symbol(staticMap, Decl(higherKindedTypes.ts, 27, 46)) +>initialX : Symbol(initialX, Decl(higherKindedTypes.ts, 14, 13)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 51, 36)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 51, 36)) + +const expectX4: FunctorX = resultX4; +>expectX4 : Symbol(expectX4, Decl(higherKindedTypes.ts, 52, 5)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypes.ts, 2, 1)) +>resultX4 : Symbol(resultX4, Decl(higherKindedTypes.ts, 51, 5)) + +const resultY4 = staticMap(initialY, val => [val]); +>resultY4 : Symbol(resultY4, Decl(higherKindedTypes.ts, 54, 5)) +>staticMap : Symbol(staticMap, Decl(higherKindedTypes.ts, 27, 46)) +>initialY : Symbol(initialY, Decl(higherKindedTypes.ts, 15, 13)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 54, 36)) +>val : Symbol(val, Decl(higherKindedTypes.ts, 54, 36)) + +const expectY4: FunctorY = resultY4; +>expectY4 : Symbol(expectY4, Decl(higherKindedTypes.ts, 55, 5)) +>FunctorY : Symbol(FunctorY, Decl(higherKindedTypes.ts, 7, 1)) +>resultY4 : Symbol(resultY4, Decl(higherKindedTypes.ts, 54, 5)) + diff --git a/tests/baselines/reference/higherKindedTypes.types b/tests/baselines/reference/higherKindedTypes.types new file mode 100644 index 0000000000000..af57cc5d2836b --- /dev/null +++ b/tests/baselines/reference/higherKindedTypes.types @@ -0,0 +1,281 @@ +=== tests/cases/compiler/higherKindedTypes.ts === +interface Functor> { +>Functor : Functor> +>A : A +>Container : Container<_T> +>_T : _T + + map(f: (a: A) => B): Container; +>map : (f: (a: A) => B) => Container +>B : B +>f : (a: A) => B +>a : A +>A : A +>B : B +>Container : Container<_T> +>B : B +} + +interface FunctorX extends Functor { +>FunctorX : FunctorX +>A : A +>Functor : Functor> +>A : A +>FunctorX : FunctorX + + map(f: (a: A) => B): FunctorX; +>map : (f: (a: A) => B) => FunctorX +>B : B +>f : (a: A) => B +>a : A +>A : A +>B : B +>FunctorX : FunctorX +>B : B + + xVal: string; +>xVal : string +} + +interface FunctorY extends Functor { +>FunctorY : FunctorY +>A : A +>Functor : Functor> +>A : A +>FunctorY : FunctorY + + map(f: (a: A) => B): FunctorY; +>map : (f: (a: A) => B) => FunctorY +>B : B +>f : (a: A) => B +>a : A +>A : A +>B : B +>FunctorY : FunctorY +>B : B + + yVal: A; +>yVal : A +>A : A +} + +declare const initialX: FunctorX; +>initialX : FunctorX +>FunctorX : FunctorX + +declare const initialY: FunctorY; +>initialY : FunctorY +>FunctorY : FunctorY + +const resultX1 = initialX.map(val => val.length); +>resultX1 : FunctorX +>initialX.map(val => val.length) : FunctorX +>initialX.map : (f: (a: string) => B) => FunctorX +>initialX : FunctorX +>map : (f: (a: string) => B) => FunctorX +>val => val.length : (val: string) => number +>val : string +>val.length : number +>val : string +>length : number + +const expectX1: FunctorX = resultX1; +>expectX1 : FunctorX +>FunctorX : FunctorX +>resultX1 : FunctorX + +const resultY1 = initialY.map(val => val.length); +>resultY1 : FunctorY +>initialY.map(val => val.length) : FunctorY +>initialY.map : (f: (a: string) => B) => FunctorY +>initialY : FunctorY +>map : (f: (a: string) => B) => FunctorY +>val => val.length : (val: string) => number +>val : string +>val.length : number +>val : string +>length : number + +const expectY1: FunctorY = resultY1; +>expectY1 : FunctorY +>FunctorY : FunctorY +>resultY1 : FunctorY + +const resultX2 = initialX.map(val => [val]); +>resultX2 : FunctorX +>initialX.map(val => [val]) : FunctorX +>initialX.map : (f: (a: string) => B) => FunctorX +>initialX : FunctorX +>map : (f: (a: string) => B) => FunctorX +>val => [val] : (val: string) => string[] +>val : string +>[val] : string[] +>val : string + +const expectX2: FunctorX = resultX2; +>expectX2 : FunctorX +>FunctorX : FunctorX +>resultX2 : FunctorX + +const resultY2 = initialY.map(val => [val]); +>resultY2 : FunctorY +>initialY.map(val => [val]) : FunctorY +>initialY.map : (f: (a: string) => B) => FunctorY +>initialY : FunctorY +>map : (f: (a: string) => B) => FunctorY +>val => [val] : (val: string) => string[] +>val : string +>[val] : string[] +>val : string + +const expectY2: FunctorY = resultY2; +>expectY2 : FunctorY +>FunctorY : FunctorY +>resultY2 : FunctorY + + +function staticMap extends Functor<_T, F>, A, B>(fa: F, f: (a: A) => B): F { +>staticMap : >, A, B>(fa: F, f: (a: A) => B) => F +>F : F<_T> +>_T : _T +>Functor : Functor> +>_T : _T +>F : F<_T> +>A : A +>B : B +>fa : F +>F : F<_T> +>A : A +>f : (a: A) => B +>a : A +>A : A +>B : B +>F : F<_T> +>B : B + + const result = fa.map(f); +>result : F +>fa.map(f) : F +>fa.map : (f: (a: A) => B) => F +>fa : F +>map : (f: (a: A) => B) => F +>f : (a: A) => B + + return result; +>result : F +} + +function staticMapBadImplementation extends Functor<_T, F>, A, B>(fa: F, f: (a: A) => B): F { +>staticMapBadImplementation : >, A, B>(fa: F, f: (a: A) => B) => F +>F : F<_T> +>_T : _T +>Functor : Functor> +>_T : _T +>F : F<_T> +>A : A +>B : B +>fa : F +>F : F<_T> +>A : A +>f : (a: A) => B +>a : A +>A : A +>B : B +>F : F<_T> +>B : B + + return fa; +>fa : F +} + +function staticMapNoConstraint, A, B>(fa: F, f: (a: A) => B): F { +>staticMapNoConstraint : (fa: F, f: (a: A) => B) => F +>F : F<_T> +>_T : _T +>A : A +>B : B +>fa : F +>F : F<_T> +>A : A +>f : (a: A) => B +>a : A +>A : A +>B : B +>F : F<_T> +>B : B + + // expect error here since F has no constraint so we have no idea what shape it will be + const result = fa.map(f); +>result : any +>fa.map(f) : any +>fa.map : any +>fa : F +>map : any +>f : (a: A) => B + + return result; +>result : any +} + +const resultX3 = staticMap(initialX, val => val.length); +>resultX3 : FunctorX +>staticMap(initialX, val => val.length) : FunctorX +>staticMap : >, A, B>(fa: F, f: (a: A) => B) => F +>initialX : FunctorX +>val => val.length : (val: string) => number +>val : string +>val.length : number +>val : string +>length : number + +const expectX3: FunctorX = resultX3; +>expectX3 : FunctorX +>FunctorX : FunctorX +>resultX3 : FunctorX + +const resultY3 = staticMap(initialY, val => val.length); +>resultY3 : FunctorY +>staticMap(initialY, val => val.length) : FunctorY +>staticMap : >, A, B>(fa: F, f: (a: A) => B) => F +>initialY : FunctorY +>val => val.length : (val: string) => number +>val : string +>val.length : number +>val : string +>length : number + +const expectY3: FunctorY = resultY3; +>expectY3 : FunctorY +>FunctorY : FunctorY +>resultY3 : FunctorY + +const resultX4 = staticMap(initialX, val => [val]); +>resultX4 : FunctorX +>staticMap(initialX, val => [val]) : FunctorX +>staticMap : >, A, B>(fa: F, f: (a: A) => B) => F +>initialX : FunctorX +>val => [val] : (val: string) => string[] +>val : string +>[val] : string[] +>val : string + +const expectX4: FunctorX = resultX4; +>expectX4 : FunctorX +>FunctorX : FunctorX +>resultX4 : FunctorX + +const resultY4 = staticMap(initialY, val => [val]); +>resultY4 : FunctorY +>staticMap(initialY, val => [val]) : FunctorY +>staticMap : >, A, B>(fa: F, f: (a: A) => B) => F +>initialY : FunctorY +>val => [val] : (val: string) => string[] +>val : string +>[val] : string[] +>val : string + +const expectY4: FunctorY = resultY4; +>expectY4 : FunctorY +>FunctorY : FunctorY +>resultY4 : FunctorY + diff --git a/tests/baselines/reference/higherKindedTypesExpectedErrors.errors.txt b/tests/baselines/reference/higherKindedTypesExpectedErrors.errors.txt new file mode 100644 index 0000000000000..2b2d58d4c26c5 --- /dev/null +++ b/tests/baselines/reference/higherKindedTypesExpectedErrors.errors.txt @@ -0,0 +1,24 @@ +tests/cases/compiler/higherKindedTypesExpectedErrors.ts(6,11): error TS2430: Interface 'FunctorX' incorrectly extends interface 'Functor, A>'. + Types of property 'map' are incompatible. + Type '(f: (a: A) => B) => B[]' is not assignable to type '(fmapx: (fmapxax: A) => BX) => FunctorX'. + Type 'BX[]' is not assignable to type 'FunctorX'. + Property 'xVal' is missing in type 'BX[]'. + + +==== tests/cases/compiler/higherKindedTypesExpectedErrors.ts (1 errors) ==== + interface Functor, AX> { + map(fmapx: (fmapxax: AX) => BX): FX; + } + + // Expect error since array doesn't have xVal property + interface FunctorX extends Functor { + ~~~~~~~~ +!!! error TS2430: Interface 'FunctorX' incorrectly extends interface 'Functor, A>'. +!!! error TS2430: Types of property 'map' are incompatible. +!!! error TS2430: Type '(f: (a: A) => B) => B[]' is not assignable to type '(fmapx: (fmapxax: A) => BX) => FunctorX'. +!!! error TS2430: Type 'BX[]' is not assignable to type 'FunctorX'. +!!! error TS2430: Property 'xVal' is missing in type 'BX[]'. + map(f: (a: A) => B): Array; + xVal: string; + } + \ No newline at end of file diff --git a/tests/baselines/reference/higherKindedTypesExpectedErrors.js b/tests/baselines/reference/higherKindedTypesExpectedErrors.js new file mode 100644 index 0000000000000..315653aa7b4cf --- /dev/null +++ b/tests/baselines/reference/higherKindedTypesExpectedErrors.js @@ -0,0 +1,13 @@ +//// [higherKindedTypesExpectedErrors.ts] +interface Functor, AX> { + map(fmapx: (fmapxax: AX) => BX): FX; +} + +// Expect error since array doesn't have xVal property +interface FunctorX extends Functor { + map(f: (a: A) => B): Array; + xVal: string; +} + + +//// [higherKindedTypesExpectedErrors.js] diff --git a/tests/baselines/reference/higherKindedTypesExpectedErrors.symbols b/tests/baselines/reference/higherKindedTypesExpectedErrors.symbols new file mode 100644 index 0000000000000..199f2699a929d --- /dev/null +++ b/tests/baselines/reference/higherKindedTypesExpectedErrors.symbols @@ -0,0 +1,40 @@ +=== tests/cases/compiler/higherKindedTypesExpectedErrors.ts === +interface Functor, AX> { +>Functor : Symbol(Functor, Decl(higherKindedTypesExpectedErrors.ts, 0, 0)) +>FX : Symbol(FX, Decl(higherKindedTypesExpectedErrors.ts, 0, 18)) +>_TX : Symbol(_TX, Decl(higherKindedTypesExpectedErrors.ts, 0, 21)) +>AX : Symbol(AX, Decl(higherKindedTypesExpectedErrors.ts, 0, 26)) + + map(fmapx: (fmapxax: AX) => BX): FX; +>map : Symbol(Functor.map, Decl(higherKindedTypesExpectedErrors.ts, 0, 32)) +>BX : Symbol(BX, Decl(higherKindedTypesExpectedErrors.ts, 1, 8)) +>fmapx : Symbol(fmapx, Decl(higherKindedTypesExpectedErrors.ts, 1, 12)) +>fmapxax : Symbol(fmapxax, Decl(higherKindedTypesExpectedErrors.ts, 1, 20)) +>AX : Symbol(AX, Decl(higherKindedTypesExpectedErrors.ts, 0, 26)) +>BX : Symbol(BX, Decl(higherKindedTypesExpectedErrors.ts, 1, 8)) +>FX : Symbol(FX, Decl(higherKindedTypesExpectedErrors.ts, 0, 18)) +>BX : Symbol(BX, Decl(higherKindedTypesExpectedErrors.ts, 1, 8)) +} + +// Expect error since array doesn't have xVal property +interface FunctorX extends Functor { +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesExpectedErrors.ts, 2, 1)) +>A : Symbol(A, Decl(higherKindedTypesExpectedErrors.ts, 5, 19)) +>Functor : Symbol(Functor, Decl(higherKindedTypesExpectedErrors.ts, 0, 0)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesExpectedErrors.ts, 2, 1)) +>A : Symbol(A, Decl(higherKindedTypesExpectedErrors.ts, 5, 19)) + + map(f: (a: A) => B): Array; +>map : Symbol(FunctorX.map, Decl(higherKindedTypesExpectedErrors.ts, 5, 52)) +>B : Symbol(B, Decl(higherKindedTypesExpectedErrors.ts, 6, 8)) +>f : Symbol(f, Decl(higherKindedTypesExpectedErrors.ts, 6, 11)) +>a : Symbol(a, Decl(higherKindedTypesExpectedErrors.ts, 6, 15)) +>A : Symbol(A, Decl(higherKindedTypesExpectedErrors.ts, 5, 19)) +>B : Symbol(B, Decl(higherKindedTypesExpectedErrors.ts, 6, 8)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>B : Symbol(B, Decl(higherKindedTypesExpectedErrors.ts, 6, 8)) + + xVal: string; +>xVal : Symbol(FunctorX.xVal, Decl(higherKindedTypesExpectedErrors.ts, 6, 37)) +} + diff --git a/tests/baselines/reference/higherKindedTypesExpectedErrors.types b/tests/baselines/reference/higherKindedTypesExpectedErrors.types new file mode 100644 index 0000000000000..ca21670126ba0 --- /dev/null +++ b/tests/baselines/reference/higherKindedTypesExpectedErrors.types @@ -0,0 +1,40 @@ +=== tests/cases/compiler/higherKindedTypesExpectedErrors.ts === +interface Functor, AX> { +>Functor : Functor, AX> +>FX : FX<_TX> +>_TX : _TX +>AX : AX + + map(fmapx: (fmapxax: AX) => BX): FX; +>map : (fmapx: (fmapxax: AX) => BX) => FX +>BX : BX +>fmapx : (fmapxax: AX) => BX +>fmapxax : AX +>AX : AX +>BX : BX +>FX : FX<_TX> +>BX : BX +} + +// Expect error since array doesn't have xVal property +interface FunctorX extends Functor { +>FunctorX : FunctorX +>A : A +>Functor : Functor, AX> +>FunctorX : FunctorX +>A : A + + map(f: (a: A) => B): Array; +>map : (f: (a: A) => B) => B[] +>B : B +>f : (a: A) => B +>a : A +>A : A +>B : B +>Array : T[] +>B : B + + xVal: string; +>xVal : string +} + diff --git a/tests/baselines/reference/higherKindedTypesLift.errors.txt b/tests/baselines/reference/higherKindedTypesLift.errors.txt new file mode 100644 index 0000000000000..fc2d667482769 --- /dev/null +++ b/tests/baselines/reference/higherKindedTypesLift.errors.txt @@ -0,0 +1,201 @@ +tests/cases/compiler/higherKindedTypesLift.ts(100,43): error TS2345: Argument of type 'FunctorX' is not assignable to parameter of type 'FunctorX'. + Type 'number' is not assignable to type 'string'. +tests/cases/compiler/higherKindedTypesLift.ts(101,43): error TS2345: Argument of type 'FunctorX' is not assignable to parameter of type 'FunctorX'. +tests/cases/compiler/higherKindedTypesLift.ts(102,43): error TS2345: Argument of type 'FunctorX' is not assignable to parameter of type 'FunctorX'. +tests/cases/compiler/higherKindedTypesLift.ts(113,48): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string[]'. + Type 'number' is not assignable to type 'string'. +tests/cases/compiler/higherKindedTypesLift.ts(114,48): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string[]'. +tests/cases/compiler/higherKindedTypesLift.ts(115,48): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string[]'. +tests/cases/compiler/higherKindedTypesLift.ts(120,43): error TS2345: Argument of type 'DiffFunctorY' is not assignable to parameter of type 'Functor>'. + Property 'map' is missing in type 'DiffFunctorY'. +tests/cases/compiler/higherKindedTypesLift.ts(121,43): error TS2345: Argument of type 'DiffFunctorY' is not assignable to parameter of type 'Functor>'. +tests/cases/compiler/higherKindedTypesLift.ts(122,43): error TS2345: Argument of type 'DiffFunctorY' is not assignable to parameter of type 'Functor>'. +tests/cases/compiler/higherKindedTypesLift.ts(125,43): error TS2345: Argument of type 'InvalidFunctor' is not assignable to parameter of type 'Functor>'. + Types of property 'map' are incompatible. + Type '(fi: (ia: string) => IB) => IB' is not assignable to type '(f: (a: string) => BF) => InvalidFunctor'. + Type 'BF' is not assignable to type 'InvalidFunctor'. +tests/cases/compiler/higherKindedTypesLift.ts(126,43): error TS2345: Argument of type 'InvalidFunctor' is not assignable to parameter of type 'Functor>'. +tests/cases/compiler/higherKindedTypesLift.ts(127,43): error TS2345: Argument of type 'InvalidFunctor' is not assignable to parameter of type 'Functor>'. +tests/cases/compiler/higherKindedTypesLift.ts(130,43): error TS2345: Argument of type 'InvalidFunctor2' is not assignable to parameter of type 'Functor>'. + Types of property 'map' are incompatible. + Type '(fi2: (ia2: string) => IB2) => FunctorX' is not assignable to type '(f: (a: string) => BF) => InvalidFunctor2'. + Type 'FunctorX' is not assignable to type 'InvalidFunctor2'. + Property 'someUniqueMethod' is missing in type 'FunctorX'. +tests/cases/compiler/higherKindedTypesLift.ts(131,43): error TS2345: Argument of type 'InvalidFunctor2' is not assignable to parameter of type 'Functor>'. +tests/cases/compiler/higherKindedTypesLift.ts(132,43): error TS2345: Argument of type 'InvalidFunctor2' is not assignable to parameter of type 'Functor>'. + + +==== tests/cases/compiler/higherKindedTypesLift.ts (15 errors) ==== + declare function stringLength(strarg: string): number; + + export interface Functor> { + map(f: (a: AF) => BF): Container; + } + + export interface DiffFunctor> { + diffMap(df: (da: DA) => DB): DContainer; + } + + class FunctorX implements Functor { + constructor(private elements: AX[]) {} + map(f: (a: AX) => BX): FunctorX { + const mappedElements = this.elements.map(f); + return new FunctorX(mappedElements); + } + + firstVal(): AX | undefined { + return this.elements.length ? this.elements[0] : undefined; + }; + } + + const functorXString = new FunctorX(["myFunctorX"]); + + declare class DiffFunctorY implements DiffFunctor { + + diffMap(f: (a: AY) => BY): DiffFunctorY + + firstValY(): AY | undefined + } + + declare const diffFunctorYString: DiffFunctorY; + + declare class InvalidFunctor { + // does not actually implement Functor because it doesn't return InvalidFunctor + map(fi: (ia: IA) => IB): IB + } + declare const invalidFunctor: InvalidFunctor; + + declare class InvalidFunctor2 { + // does not actually implement Functor because it doesn't return InvalidFunctor2 + map(fi2: (ia2: IA2) => IB2): FunctorX + + someUniqueMethod(): IA2 + } + declare const invalidFunctor2: InvalidFunctor2; + + interface StaticFunctor> { + (csas: CS, fmapstatic: (as: AS) => BS): CS; + } + + interface LiftedResult> { + (lrmap: (lra: LRA) => LRB): extends LRC<_NT>>(lrclra: NC) => NC + } + + interface LiftedResult3A> { + (lrmap: (lra: LRA) => LRB): LiftedResult3B + } + interface LiftedResult3B, LRA, LRB> { + extends LRC<_NT>>(lrclra: NC): NC + } + + function lift1>(fToLift: StaticFunctor): LiftedResult { + return lmap => lca => fToLift(lca, lmap); + } + + // lift2 does not use intermediate interfaces + function lift2>( + fToLift: (csas: C, fmapstatic: (as: AS) => BS) => C + ): + (lrmap: (lra: LA) => LB) => extends C<_NT>>(lrclra: NC) => NC { + return lmap => lca => fToLift(lca, lmap); + } + + // lift3 uses an extra intermediate interface + function lift3>(fToLift: StaticFunctor): LiftedResult3A { + return lmap => lca => fToLift(lca, lmap); + } + + function staticMap extends Functor<_T1, C1>, A1, B1>(fa1: C1, fmap1: (a1: A1) => B1): C1 { + return fa1.map(fmap1); + } + + const liftedFunctor1 = lift1(staticMap); + const liftedFunctor2 = lift2(staticMap); + const liftedFunctor3 = lift3(staticMap); + + const liftedStringLength1 = liftedFunctor1(stringLength); + const liftedStringLength2 = liftedFunctor2(stringLength); + const liftedStringLength3 = liftedFunctor3(stringLength); + + + const result1 = liftedStringLength1(functorXString); + const expectedType1: FunctorX = result1; + const result2 = liftedStringLength2(functorXString); + const expectedType2: FunctorX = result2; + const result3 = liftedStringLength3(functorXString); + const expectedType3: FunctorX = result3; + + const expectErrorA1 = liftedStringLength1(result1); + ~~~~~~~ +!!! error TS2345: Argument of type 'FunctorX' is not assignable to parameter of type 'FunctorX'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + const expectErrorA2 = liftedStringLength2(result2); + ~~~~~~~ +!!! error TS2345: Argument of type 'FunctorX' is not assignable to parameter of type 'FunctorX'. + const expectErrorA3 = liftedStringLength3(result3); + ~~~~~~~ +!!! error TS2345: Argument of type 'FunctorX' is not assignable to parameter of type 'FunctorX'. + + + const stringArray = ["not explicitly declared to implement functor"]; + const arrayResult1 = liftedStringLength1(stringArray); + const arrayExpectedType1: Array = arrayResult1; + const arrayResult2 = liftedStringLength2(stringArray); + const arrayExpectedType2: Array = arrayResult2; + const arrayResult3 = liftedStringLength3(stringArray); + const arrayExpectedType3: Array = arrayResult3; + + const arrayExpectErrorA1 = liftedStringLength1(arrayResult1); + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string[]'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. + const arrayExpectErrorA2 = liftedStringLength2(arrayResult2); + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string[]'. + const arrayExpectErrorA3 = liftedStringLength3(arrayResult3); + ~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string[]'. + + + + // should have error because DiffFunctorY has diffMap function, not "map" as needed because liftedFunctor was created from staticMap which declared Functor + const expectErrorB1 = liftedStringLength1(diffFunctorYString); + ~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'DiffFunctorY' is not assignable to parameter of type 'Functor>'. +!!! error TS2345: Property 'map' is missing in type 'DiffFunctorY'. + const expectErrorB2 = liftedStringLength2(diffFunctorYString); + ~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'DiffFunctorY' is not assignable to parameter of type 'Functor>'. + const expectErrorB3 = liftedStringLength3(diffFunctorYString); + ~~~~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'DiffFunctorY' is not assignable to parameter of type 'Functor>'. + + + const expectErrorC1 = liftedStringLength1(invalidFunctor); + ~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'InvalidFunctor' is not assignable to parameter of type 'Functor>'. +!!! error TS2345: Types of property 'map' are incompatible. +!!! error TS2345: Type '(fi: (ia: string) => IB) => IB' is not assignable to type '(f: (a: string) => BF) => InvalidFunctor'. +!!! error TS2345: Type 'BF' is not assignable to type 'InvalidFunctor'. + const expectErrorC2 = liftedStringLength2(invalidFunctor); + ~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'InvalidFunctor' is not assignable to parameter of type 'Functor>'. + const expectErrorC3 = liftedStringLength3(invalidFunctor); + ~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'InvalidFunctor' is not assignable to parameter of type 'Functor>'. + + + const expectErrorD1 = liftedStringLength1(invalidFunctor2); + ~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'InvalidFunctor2' is not assignable to parameter of type 'Functor>'. +!!! error TS2345: Types of property 'map' are incompatible. +!!! error TS2345: Type '(fi2: (ia2: string) => IB2) => FunctorX' is not assignable to type '(f: (a: string) => BF) => InvalidFunctor2'. +!!! error TS2345: Type 'FunctorX' is not assignable to type 'InvalidFunctor2'. +!!! error TS2345: Property 'someUniqueMethod' is missing in type 'FunctorX'. + const expectErrorD2 = liftedStringLength2(invalidFunctor2); + ~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'InvalidFunctor2' is not assignable to parameter of type 'Functor>'. + const expectErrorD3 = liftedStringLength3(invalidFunctor2); + ~~~~~~~~~~~~~~~ +!!! error TS2345: Argument of type 'InvalidFunctor2' is not assignable to parameter of type 'Functor>'. + \ No newline at end of file diff --git a/tests/baselines/reference/higherKindedTypesLift.js b/tests/baselines/reference/higherKindedTypesLift.js new file mode 100644 index 0000000000000..a9ac9143e7b85 --- /dev/null +++ b/tests/baselines/reference/higherKindedTypesLift.js @@ -0,0 +1,202 @@ +//// [higherKindedTypesLift.ts] +declare function stringLength(strarg: string): number; + +export interface Functor> { + map(f: (a: AF) => BF): Container; +} + +export interface DiffFunctor> { + diffMap(df: (da: DA) => DB): DContainer; +} + +class FunctorX implements Functor { + constructor(private elements: AX[]) {} + map(f: (a: AX) => BX): FunctorX { + const mappedElements = this.elements.map(f); + return new FunctorX(mappedElements); + } + + firstVal(): AX | undefined { + return this.elements.length ? this.elements[0] : undefined; + }; +} + +const functorXString = new FunctorX(["myFunctorX"]); + +declare class DiffFunctorY implements DiffFunctor { + + diffMap(f: (a: AY) => BY): DiffFunctorY + + firstValY(): AY | undefined +} + +declare const diffFunctorYString: DiffFunctorY; + +declare class InvalidFunctor { + // does not actually implement Functor because it doesn't return InvalidFunctor + map(fi: (ia: IA) => IB): IB +} +declare const invalidFunctor: InvalidFunctor; + +declare class InvalidFunctor2 { + // does not actually implement Functor because it doesn't return InvalidFunctor2 + map(fi2: (ia2: IA2) => IB2): FunctorX + + someUniqueMethod(): IA2 +} +declare const invalidFunctor2: InvalidFunctor2; + +interface StaticFunctor> { + (csas: CS, fmapstatic: (as: AS) => BS): CS; +} + +interface LiftedResult> { + (lrmap: (lra: LRA) => LRB): extends LRC<_NT>>(lrclra: NC) => NC +} + +interface LiftedResult3A> { + (lrmap: (lra: LRA) => LRB): LiftedResult3B +} +interface LiftedResult3B, LRA, LRB> { + extends LRC<_NT>>(lrclra: NC): NC +} + +function lift1>(fToLift: StaticFunctor): LiftedResult { + return lmap => lca => fToLift(lca, lmap); +} + +// lift2 does not use intermediate interfaces +function lift2>( + fToLift: (csas: C, fmapstatic: (as: AS) => BS) => C +): + (lrmap: (lra: LA) => LB) => extends C<_NT>>(lrclra: NC) => NC { + return lmap => lca => fToLift(lca, lmap); +} + +// lift3 uses an extra intermediate interface +function lift3>(fToLift: StaticFunctor): LiftedResult3A { + return lmap => lca => fToLift(lca, lmap); +} + +function staticMap extends Functor<_T1, C1>, A1, B1>(fa1: C1, fmap1: (a1: A1) => B1): C1 { + return fa1.map(fmap1); +} + +const liftedFunctor1 = lift1(staticMap); +const liftedFunctor2 = lift2(staticMap); +const liftedFunctor3 = lift3(staticMap); + +const liftedStringLength1 = liftedFunctor1(stringLength); +const liftedStringLength2 = liftedFunctor2(stringLength); +const liftedStringLength3 = liftedFunctor3(stringLength); + + +const result1 = liftedStringLength1(functorXString); +const expectedType1: FunctorX = result1; +const result2 = liftedStringLength2(functorXString); +const expectedType2: FunctorX = result2; +const result3 = liftedStringLength3(functorXString); +const expectedType3: FunctorX = result3; + +const expectErrorA1 = liftedStringLength1(result1); +const expectErrorA2 = liftedStringLength2(result2); +const expectErrorA3 = liftedStringLength3(result3); + + +const stringArray = ["not explicitly declared to implement functor"]; +const arrayResult1 = liftedStringLength1(stringArray); +const arrayExpectedType1: Array = arrayResult1; +const arrayResult2 = liftedStringLength2(stringArray); +const arrayExpectedType2: Array = arrayResult2; +const arrayResult3 = liftedStringLength3(stringArray); +const arrayExpectedType3: Array = arrayResult3; + +const arrayExpectErrorA1 = liftedStringLength1(arrayResult1); +const arrayExpectErrorA2 = liftedStringLength2(arrayResult2); +const arrayExpectErrorA3 = liftedStringLength3(arrayResult3); + + + +// should have error because DiffFunctorY has diffMap function, not "map" as needed because liftedFunctor was created from staticMap which declared Functor +const expectErrorB1 = liftedStringLength1(diffFunctorYString); +const expectErrorB2 = liftedStringLength2(diffFunctorYString); +const expectErrorB3 = liftedStringLength3(diffFunctorYString); + + +const expectErrorC1 = liftedStringLength1(invalidFunctor); +const expectErrorC2 = liftedStringLength2(invalidFunctor); +const expectErrorC3 = liftedStringLength3(invalidFunctor); + + +const expectErrorD1 = liftedStringLength1(invalidFunctor2); +const expectErrorD2 = liftedStringLength2(invalidFunctor2); +const expectErrorD3 = liftedStringLength3(invalidFunctor2); + + +//// [higherKindedTypesLift.js] +"use strict"; +exports.__esModule = true; +var FunctorX = /** @class */ (function () { + function FunctorX(elements) { + this.elements = elements; + } + FunctorX.prototype.map = function (f) { + var mappedElements = this.elements.map(f); + return new FunctorX(mappedElements); + }; + FunctorX.prototype.firstVal = function () { + return this.elements.length ? this.elements[0] : undefined; + }; + ; + return FunctorX; +}()); +var functorXString = new FunctorX(["myFunctorX"]); +function lift1(fToLift) { + return function (lmap) { return function (lca) { return fToLift(lca, lmap); }; }; +} +// lift2 does not use intermediate interfaces +function lift2(fToLift) { + return function (lmap) { return function (lca) { return fToLift(lca, lmap); }; }; +} +// lift3 uses an extra intermediate interface +function lift3(fToLift) { + return function (lmap) { return function (lca) { return fToLift(lca, lmap); }; }; +} +function staticMap(fa1, fmap1) { + return fa1.map(fmap1); +} +var liftedFunctor1 = lift1(staticMap); +var liftedFunctor2 = lift2(staticMap); +var liftedFunctor3 = lift3(staticMap); +var liftedStringLength1 = liftedFunctor1(stringLength); +var liftedStringLength2 = liftedFunctor2(stringLength); +var liftedStringLength3 = liftedFunctor3(stringLength); +var result1 = liftedStringLength1(functorXString); +var expectedType1 = result1; +var result2 = liftedStringLength2(functorXString); +var expectedType2 = result2; +var result3 = liftedStringLength3(functorXString); +var expectedType3 = result3; +var expectErrorA1 = liftedStringLength1(result1); +var expectErrorA2 = liftedStringLength2(result2); +var expectErrorA3 = liftedStringLength3(result3); +var stringArray = ["not explicitly declared to implement functor"]; +var arrayResult1 = liftedStringLength1(stringArray); +var arrayExpectedType1 = arrayResult1; +var arrayResult2 = liftedStringLength2(stringArray); +var arrayExpectedType2 = arrayResult2; +var arrayResult3 = liftedStringLength3(stringArray); +var arrayExpectedType3 = arrayResult3; +var arrayExpectErrorA1 = liftedStringLength1(arrayResult1); +var arrayExpectErrorA2 = liftedStringLength2(arrayResult2); +var arrayExpectErrorA3 = liftedStringLength3(arrayResult3); +// should have error because DiffFunctorY has diffMap function, not "map" as needed because liftedFunctor was created from staticMap which declared Functor +var expectErrorB1 = liftedStringLength1(diffFunctorYString); +var expectErrorB2 = liftedStringLength2(diffFunctorYString); +var expectErrorB3 = liftedStringLength3(diffFunctorYString); +var expectErrorC1 = liftedStringLength1(invalidFunctor); +var expectErrorC2 = liftedStringLength2(invalidFunctor); +var expectErrorC3 = liftedStringLength3(invalidFunctor); +var expectErrorD1 = liftedStringLength1(invalidFunctor2); +var expectErrorD2 = liftedStringLength2(invalidFunctor2); +var expectErrorD3 = liftedStringLength3(invalidFunctor2); diff --git a/tests/baselines/reference/higherKindedTypesLift.symbols b/tests/baselines/reference/higherKindedTypesLift.symbols new file mode 100644 index 0000000000000..14621bc60ebb9 --- /dev/null +++ b/tests/baselines/reference/higherKindedTypesLift.symbols @@ -0,0 +1,525 @@ +=== tests/cases/compiler/higherKindedTypesLift.ts === +declare function stringLength(strarg: string): number; +>stringLength : Symbol(stringLength, Decl(higherKindedTypesLift.ts, 0, 0)) +>strarg : Symbol(strarg, Decl(higherKindedTypesLift.ts, 0, 30)) + +export interface Functor> { +>Functor : Symbol(Functor, Decl(higherKindedTypesLift.ts, 0, 54)) +>AF : Symbol(AF, Decl(higherKindedTypesLift.ts, 2, 25)) +>Container : Symbol(Container, Decl(higherKindedTypesLift.ts, 2, 28)) +>_TF : Symbol(_TF, Decl(higherKindedTypesLift.ts, 2, 39)) + + map(f: (a: AF) => BF): Container; +>map : Symbol(Functor.map, Decl(higherKindedTypesLift.ts, 2, 46)) +>BF : Symbol(BF, Decl(higherKindedTypesLift.ts, 3, 8)) +>f : Symbol(f, Decl(higherKindedTypesLift.ts, 3, 12)) +>a : Symbol(a, Decl(higherKindedTypesLift.ts, 3, 16)) +>AF : Symbol(AF, Decl(higherKindedTypesLift.ts, 2, 25)) +>BF : Symbol(BF, Decl(higherKindedTypesLift.ts, 3, 8)) +>Container : Symbol(Container, Decl(higherKindedTypesLift.ts, 2, 28)) +>BF : Symbol(BF, Decl(higherKindedTypesLift.ts, 3, 8)) +} + +export interface DiffFunctor> { +>DiffFunctor : Symbol(DiffFunctor, Decl(higherKindedTypesLift.ts, 4, 1)) +>DA : Symbol(DA, Decl(higherKindedTypesLift.ts, 6, 29)) +>DContainer : Symbol(DContainer, Decl(higherKindedTypesLift.ts, 6, 32)) +>_TD : Symbol(_TD, Decl(higherKindedTypesLift.ts, 6, 44)) + + diffMap(df: (da: DA) => DB): DContainer; +>diffMap : Symbol(DiffFunctor.diffMap, Decl(higherKindedTypesLift.ts, 6, 51)) +>DB : Symbol(DB, Decl(higherKindedTypesLift.ts, 7, 12)) +>df : Symbol(df, Decl(higherKindedTypesLift.ts, 7, 16)) +>da : Symbol(da, Decl(higherKindedTypesLift.ts, 7, 21)) +>DA : Symbol(DA, Decl(higherKindedTypesLift.ts, 6, 29)) +>DB : Symbol(DB, Decl(higherKindedTypesLift.ts, 7, 12)) +>DContainer : Symbol(DContainer, Decl(higherKindedTypesLift.ts, 6, 32)) +>DB : Symbol(DB, Decl(higherKindedTypesLift.ts, 7, 12)) +} + +class FunctorX implements Functor { +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) +>AX : Symbol(AX, Decl(higherKindedTypesLift.ts, 10, 15)) +>Functor : Symbol(Functor, Decl(higherKindedTypesLift.ts, 0, 54)) +>AX : Symbol(AX, Decl(higherKindedTypesLift.ts, 10, 15)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) + + constructor(private elements: AX[]) {} +>elements : Symbol(FunctorX.elements, Decl(higherKindedTypesLift.ts, 11, 16)) +>AX : Symbol(AX, Decl(higherKindedTypesLift.ts, 10, 15)) + + map(f: (a: AX) => BX): FunctorX { +>map : Symbol(FunctorX.map, Decl(higherKindedTypesLift.ts, 11, 42)) +>BX : Symbol(BX, Decl(higherKindedTypesLift.ts, 12, 8)) +>f : Symbol(f, Decl(higherKindedTypesLift.ts, 12, 12)) +>a : Symbol(a, Decl(higherKindedTypesLift.ts, 12, 16)) +>AX : Symbol(AX, Decl(higherKindedTypesLift.ts, 10, 15)) +>BX : Symbol(BX, Decl(higherKindedTypesLift.ts, 12, 8)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) +>BX : Symbol(BX, Decl(higherKindedTypesLift.ts, 12, 8)) + + const mappedElements = this.elements.map(f); +>mappedElements : Symbol(mappedElements, Decl(higherKindedTypesLift.ts, 13, 13)) +>this.elements.map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>this.elements : Symbol(FunctorX.elements, Decl(higherKindedTypesLift.ts, 11, 16)) +>this : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) +>elements : Symbol(FunctorX.elements, Decl(higherKindedTypesLift.ts, 11, 16)) +>map : Symbol(Array.map, Decl(lib.d.ts, --, --)) +>f : Symbol(f, Decl(higherKindedTypesLift.ts, 12, 12)) + + return new FunctorX(mappedElements); +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) +>mappedElements : Symbol(mappedElements, Decl(higherKindedTypesLift.ts, 13, 13)) + } + + firstVal(): AX | undefined { +>firstVal : Symbol(FunctorX.firstVal, Decl(higherKindedTypesLift.ts, 15, 5)) +>AX : Symbol(AX, Decl(higherKindedTypesLift.ts, 10, 15)) + + return this.elements.length ? this.elements[0] : undefined; +>this.elements.length : Symbol(Array.length, Decl(lib.d.ts, --, --)) +>this.elements : Symbol(FunctorX.elements, Decl(higherKindedTypesLift.ts, 11, 16)) +>this : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) +>elements : Symbol(FunctorX.elements, Decl(higherKindedTypesLift.ts, 11, 16)) +>length : Symbol(Array.length, Decl(lib.d.ts, --, --)) +>this.elements : Symbol(FunctorX.elements, Decl(higherKindedTypesLift.ts, 11, 16)) +>this : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) +>elements : Symbol(FunctorX.elements, Decl(higherKindedTypesLift.ts, 11, 16)) +>undefined : Symbol(undefined) + + }; +} + +const functorXString = new FunctorX(["myFunctorX"]); +>functorXString : Symbol(functorXString, Decl(higherKindedTypesLift.ts, 22, 5)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) + +declare class DiffFunctorY implements DiffFunctor { +>DiffFunctorY : Symbol(DiffFunctorY, Decl(higherKindedTypesLift.ts, 22, 52)) +>AY : Symbol(AY, Decl(higherKindedTypesLift.ts, 24, 27)) +>DiffFunctor : Symbol(DiffFunctor, Decl(higherKindedTypesLift.ts, 4, 1)) +>AY : Symbol(AY, Decl(higherKindedTypesLift.ts, 24, 27)) +>DiffFunctorY : Symbol(DiffFunctorY, Decl(higherKindedTypesLift.ts, 22, 52)) + + diffMap(f: (a: AY) => BY): DiffFunctorY +>diffMap : Symbol(DiffFunctorY.diffMap, Decl(higherKindedTypesLift.ts, 24, 73)) +>BY : Symbol(BY, Decl(higherKindedTypesLift.ts, 26, 12)) +>f : Symbol(f, Decl(higherKindedTypesLift.ts, 26, 16)) +>a : Symbol(a, Decl(higherKindedTypesLift.ts, 26, 20)) +>AY : Symbol(AY, Decl(higherKindedTypesLift.ts, 24, 27)) +>BY : Symbol(BY, Decl(higherKindedTypesLift.ts, 26, 12)) +>DiffFunctorY : Symbol(DiffFunctorY, Decl(higherKindedTypesLift.ts, 22, 52)) +>BY : Symbol(BY, Decl(higherKindedTypesLift.ts, 26, 12)) + + firstValY(): AY | undefined +>firstValY : Symbol(DiffFunctorY.firstValY, Decl(higherKindedTypesLift.ts, 26, 51)) +>AY : Symbol(AY, Decl(higherKindedTypesLift.ts, 24, 27)) +} + +declare const diffFunctorYString: DiffFunctorY; +>diffFunctorYString : Symbol(diffFunctorYString, Decl(higherKindedTypesLift.ts, 31, 13)) +>DiffFunctorY : Symbol(DiffFunctorY, Decl(higherKindedTypesLift.ts, 22, 52)) + +declare class InvalidFunctor { +>InvalidFunctor : Symbol(InvalidFunctor, Decl(higherKindedTypesLift.ts, 31, 55)) +>IA : Symbol(IA, Decl(higherKindedTypesLift.ts, 33, 29)) + + // does not actually implement Functor because it doesn't return InvalidFunctor + map(fi: (ia: IA) => IB): IB +>map : Symbol(InvalidFunctor.map, Decl(higherKindedTypesLift.ts, 33, 34)) +>IB : Symbol(IB, Decl(higherKindedTypesLift.ts, 35, 8)) +>fi : Symbol(fi, Decl(higherKindedTypesLift.ts, 35, 12)) +>ia : Symbol(ia, Decl(higherKindedTypesLift.ts, 35, 17)) +>IA : Symbol(IA, Decl(higherKindedTypesLift.ts, 33, 29)) +>IB : Symbol(IB, Decl(higherKindedTypesLift.ts, 35, 8)) +>IB : Symbol(IB, Decl(higherKindedTypesLift.ts, 35, 8)) +} +declare const invalidFunctor: InvalidFunctor; +>invalidFunctor : Symbol(invalidFunctor, Decl(higherKindedTypesLift.ts, 37, 13)) +>InvalidFunctor : Symbol(InvalidFunctor, Decl(higherKindedTypesLift.ts, 31, 55)) + +declare class InvalidFunctor2 { +>InvalidFunctor2 : Symbol(InvalidFunctor2, Decl(higherKindedTypesLift.ts, 37, 53)) +>IA2 : Symbol(IA2, Decl(higherKindedTypesLift.ts, 39, 30)) + + // does not actually implement Functor because it doesn't return InvalidFunctor2 + map(fi2: (ia2: IA2) => IB2): FunctorX +>map : Symbol(InvalidFunctor2.map, Decl(higherKindedTypesLift.ts, 39, 36)) +>IB2 : Symbol(IB2, Decl(higherKindedTypesLift.ts, 41, 8)) +>fi2 : Symbol(fi2, Decl(higherKindedTypesLift.ts, 41, 13)) +>ia2 : Symbol(ia2, Decl(higherKindedTypesLift.ts, 41, 19)) +>IA2 : Symbol(IA2, Decl(higherKindedTypesLift.ts, 39, 30)) +>IB2 : Symbol(IB2, Decl(higherKindedTypesLift.ts, 41, 8)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) +>IB2 : Symbol(IB2, Decl(higherKindedTypesLift.ts, 41, 8)) + + someUniqueMethod(): IA2 +>someUniqueMethod : Symbol(InvalidFunctor2.someUniqueMethod, Decl(higherKindedTypesLift.ts, 41, 51)) +>IA2 : Symbol(IA2, Decl(higherKindedTypesLift.ts, 39, 30)) +} +declare const invalidFunctor2: InvalidFunctor2; +>invalidFunctor2 : Symbol(invalidFunctor2, Decl(higherKindedTypesLift.ts, 45, 13)) +>InvalidFunctor2 : Symbol(InvalidFunctor2, Decl(higherKindedTypesLift.ts, 37, 53)) + +interface StaticFunctor> { +>StaticFunctor : Symbol(StaticFunctor, Decl(higherKindedTypesLift.ts, 45, 55)) +>CS : Symbol(CS, Decl(higherKindedTypesLift.ts, 47, 24)) +>_TS : Symbol(_TS, Decl(higherKindedTypesLift.ts, 47, 27)) + + (csas: CS, fmapstatic: (as: AS) => BS): CS; +>AS : Symbol(AS, Decl(higherKindedTypesLift.ts, 48, 5)) +>BS : Symbol(BS, Decl(higherKindedTypesLift.ts, 48, 8)) +>csas : Symbol(csas, Decl(higherKindedTypesLift.ts, 48, 13)) +>CS : Symbol(CS, Decl(higherKindedTypesLift.ts, 47, 24)) +>AS : Symbol(AS, Decl(higherKindedTypesLift.ts, 48, 5)) +>fmapstatic : Symbol(fmapstatic, Decl(higherKindedTypesLift.ts, 48, 26)) +>as : Symbol(as, Decl(higherKindedTypesLift.ts, 48, 40)) +>AS : Symbol(AS, Decl(higherKindedTypesLift.ts, 48, 5)) +>BS : Symbol(BS, Decl(higherKindedTypesLift.ts, 48, 8)) +>CS : Symbol(CS, Decl(higherKindedTypesLift.ts, 47, 24)) +>BS : Symbol(BS, Decl(higherKindedTypesLift.ts, 48, 8)) +} + +interface LiftedResult> { +>LiftedResult : Symbol(LiftedResult, Decl(higherKindedTypesLift.ts, 49, 1)) +>LRC : Symbol(LRC, Decl(higherKindedTypesLift.ts, 51, 23)) +>_LT : Symbol(_LT, Decl(higherKindedTypesLift.ts, 51, 27)) + + (lrmap: (lra: LRA) => LRB): extends LRC<_NT>>(lrclra: NC) => NC +>LRA : Symbol(LRA, Decl(higherKindedTypesLift.ts, 52, 5)) +>LRB : Symbol(LRB, Decl(higherKindedTypesLift.ts, 52, 9)) +>lrmap : Symbol(lrmap, Decl(higherKindedTypesLift.ts, 52, 15)) +>lra : Symbol(lra, Decl(higherKindedTypesLift.ts, 52, 23)) +>LRA : Symbol(LRA, Decl(higherKindedTypesLift.ts, 52, 5)) +>LRB : Symbol(LRB, Decl(higherKindedTypesLift.ts, 52, 9)) +>NC : Symbol(NC, Decl(higherKindedTypesLift.ts, 52, 43)) +>_NT : Symbol(_NT, Decl(higherKindedTypesLift.ts, 52, 46)) +>LRC : Symbol(LRC, Decl(higherKindedTypesLift.ts, 51, 23)) +>_NT : Symbol(_NT, Decl(higherKindedTypesLift.ts, 52, 46)) +>lrclra : Symbol(lrclra, Decl(higherKindedTypesLift.ts, 52, 69)) +>NC : Symbol(NC, Decl(higherKindedTypesLift.ts, 52, 43)) +>LRA : Symbol(LRA, Decl(higherKindedTypesLift.ts, 52, 5)) +>NC : Symbol(NC, Decl(higherKindedTypesLift.ts, 52, 43)) +>LRB : Symbol(LRB, Decl(higherKindedTypesLift.ts, 52, 9)) +} + +interface LiftedResult3A> { +>LiftedResult3A : Symbol(LiftedResult3A, Decl(higherKindedTypesLift.ts, 53, 1)) +>LRC : Symbol(LRC, Decl(higherKindedTypesLift.ts, 55, 25)) +>_LT : Symbol(_LT, Decl(higherKindedTypesLift.ts, 55, 29)) + + (lrmap: (lra: LRA) => LRB): LiftedResult3B +>LRA : Symbol(LRA, Decl(higherKindedTypesLift.ts, 56, 5)) +>LRB : Symbol(LRB, Decl(higherKindedTypesLift.ts, 56, 9)) +>lrmap : Symbol(lrmap, Decl(higherKindedTypesLift.ts, 56, 15)) +>lra : Symbol(lra, Decl(higherKindedTypesLift.ts, 56, 23)) +>LRA : Symbol(LRA, Decl(higherKindedTypesLift.ts, 56, 5)) +>LRB : Symbol(LRB, Decl(higherKindedTypesLift.ts, 56, 9)) +>LiftedResult3B : Symbol(LiftedResult3B, Decl(higherKindedTypesLift.ts, 57, 1)) +>LRC : Symbol(LRC, Decl(higherKindedTypesLift.ts, 55, 25)) +>LRA : Symbol(LRA, Decl(higherKindedTypesLift.ts, 56, 5)) +>LRB : Symbol(LRB, Decl(higherKindedTypesLift.ts, 56, 9)) +} +interface LiftedResult3B, LRA, LRB> { +>LiftedResult3B : Symbol(LiftedResult3B, Decl(higherKindedTypesLift.ts, 57, 1)) +>LRC : Symbol(LRC, Decl(higherKindedTypesLift.ts, 58, 25)) +>_LT : Symbol(_LT, Decl(higherKindedTypesLift.ts, 58, 29)) +>LRA : Symbol(LRA, Decl(higherKindedTypesLift.ts, 58, 34)) +>LRB : Symbol(LRB, Decl(higherKindedTypesLift.ts, 58, 39)) + + extends LRC<_NT>>(lrclra: NC): NC +>NC : Symbol(NC, Decl(higherKindedTypesLift.ts, 59, 5)) +>_NT : Symbol(_NT, Decl(higherKindedTypesLift.ts, 59, 8)) +>LRC : Symbol(LRC, Decl(higherKindedTypesLift.ts, 58, 25)) +>_NT : Symbol(_NT, Decl(higherKindedTypesLift.ts, 59, 8)) +>lrclra : Symbol(lrclra, Decl(higherKindedTypesLift.ts, 59, 31)) +>NC : Symbol(NC, Decl(higherKindedTypesLift.ts, 59, 5)) +>LRA : Symbol(LRA, Decl(higherKindedTypesLift.ts, 58, 34)) +>NC : Symbol(NC, Decl(higherKindedTypesLift.ts, 59, 5)) +>LRB : Symbol(LRB, Decl(higherKindedTypesLift.ts, 58, 39)) +} + +function lift1>(fToLift: StaticFunctor): LiftedResult { +>lift1 : Symbol(lift1, Decl(higherKindedTypesLift.ts, 60, 1)) +>C : Symbol(C, Decl(higherKindedTypesLift.ts, 62, 15)) +>_TL : Symbol(_TL, Decl(higherKindedTypesLift.ts, 62, 17)) +>fToLift : Symbol(fToLift, Decl(higherKindedTypesLift.ts, 62, 23)) +>StaticFunctor : Symbol(StaticFunctor, Decl(higherKindedTypesLift.ts, 45, 55)) +>C : Symbol(C, Decl(higherKindedTypesLift.ts, 62, 15)) +>LiftedResult : Symbol(LiftedResult, Decl(higherKindedTypesLift.ts, 49, 1)) +>C : Symbol(C, Decl(higherKindedTypesLift.ts, 62, 15)) + + return lmap => lca => fToLift(lca, lmap); +>lmap : Symbol(lmap, Decl(higherKindedTypesLift.ts, 63, 10)) +>lca : Symbol(lca, Decl(higherKindedTypesLift.ts, 63, 18)) +>fToLift : Symbol(fToLift, Decl(higherKindedTypesLift.ts, 62, 23)) +>lca : Symbol(lca, Decl(higherKindedTypesLift.ts, 63, 18)) +>lmap : Symbol(lmap, Decl(higherKindedTypesLift.ts, 63, 10)) +} + +// lift2 does not use intermediate interfaces +function lift2>( +>lift2 : Symbol(lift2, Decl(higherKindedTypesLift.ts, 64, 1)) +>C : Symbol(C, Decl(higherKindedTypesLift.ts, 67, 15)) +>_TL : Symbol(_TL, Decl(higherKindedTypesLift.ts, 67, 17)) + + fToLift: (csas: C, fmapstatic: (as: AS) => BS) => C +>fToLift : Symbol(fToLift, Decl(higherKindedTypesLift.ts, 67, 23)) +>AS : Symbol(AS, Decl(higherKindedTypesLift.ts, 68, 14)) +>BS : Symbol(BS, Decl(higherKindedTypesLift.ts, 68, 17)) +>csas : Symbol(csas, Decl(higherKindedTypesLift.ts, 68, 22)) +>C : Symbol(C, Decl(higherKindedTypesLift.ts, 67, 15)) +>AS : Symbol(AS, Decl(higherKindedTypesLift.ts, 68, 14)) +>fmapstatic : Symbol(fmapstatic, Decl(higherKindedTypesLift.ts, 68, 34)) +>as : Symbol(as, Decl(higherKindedTypesLift.ts, 68, 48)) +>AS : Symbol(AS, Decl(higherKindedTypesLift.ts, 68, 14)) +>BS : Symbol(BS, Decl(higherKindedTypesLift.ts, 68, 17)) +>C : Symbol(C, Decl(higherKindedTypesLift.ts, 67, 15)) +>BS : Symbol(BS, Decl(higherKindedTypesLift.ts, 68, 17)) + +): + (lrmap: (lra: LA) => LB) => extends C<_NT>>(lrclra: NC) => NC { +>LA : Symbol(LA, Decl(higherKindedTypesLift.ts, 70, 5)) +>LB : Symbol(LB, Decl(higherKindedTypesLift.ts, 70, 8)) +>lrmap : Symbol(lrmap, Decl(higherKindedTypesLift.ts, 70, 13)) +>lra : Symbol(lra, Decl(higherKindedTypesLift.ts, 70, 21)) +>LA : Symbol(LA, Decl(higherKindedTypesLift.ts, 70, 5)) +>LB : Symbol(LB, Decl(higherKindedTypesLift.ts, 70, 8)) +>NC : Symbol(NC, Decl(higherKindedTypesLift.ts, 70, 41)) +>_NT : Symbol(_NT, Decl(higherKindedTypesLift.ts, 70, 44)) +>C : Symbol(C, Decl(higherKindedTypesLift.ts, 67, 15)) +>_NT : Symbol(_NT, Decl(higherKindedTypesLift.ts, 70, 44)) +>lrclra : Symbol(lrclra, Decl(higherKindedTypesLift.ts, 70, 65)) +>NC : Symbol(NC, Decl(higherKindedTypesLift.ts, 70, 41)) +>LA : Symbol(LA, Decl(higherKindedTypesLift.ts, 70, 5)) +>NC : Symbol(NC, Decl(higherKindedTypesLift.ts, 70, 41)) +>LB : Symbol(LB, Decl(higherKindedTypesLift.ts, 70, 8)) + + return lmap => lca => fToLift(lca, lmap); +>lmap : Symbol(lmap, Decl(higherKindedTypesLift.ts, 71, 10)) +>lca : Symbol(lca, Decl(higherKindedTypesLift.ts, 71, 18)) +>fToLift : Symbol(fToLift, Decl(higherKindedTypesLift.ts, 67, 23)) +>lca : Symbol(lca, Decl(higherKindedTypesLift.ts, 71, 18)) +>lmap : Symbol(lmap, Decl(higherKindedTypesLift.ts, 71, 10)) +} + +// lift3 uses an extra intermediate interface +function lift3>(fToLift: StaticFunctor): LiftedResult3A { +>lift3 : Symbol(lift3, Decl(higherKindedTypesLift.ts, 72, 1)) +>C : Symbol(C, Decl(higherKindedTypesLift.ts, 75, 15)) +>_TL : Symbol(_TL, Decl(higherKindedTypesLift.ts, 75, 17)) +>fToLift : Symbol(fToLift, Decl(higherKindedTypesLift.ts, 75, 23)) +>StaticFunctor : Symbol(StaticFunctor, Decl(higherKindedTypesLift.ts, 45, 55)) +>C : Symbol(C, Decl(higherKindedTypesLift.ts, 75, 15)) +>LiftedResult3A : Symbol(LiftedResult3A, Decl(higherKindedTypesLift.ts, 53, 1)) +>C : Symbol(C, Decl(higherKindedTypesLift.ts, 75, 15)) + + return lmap => lca => fToLift(lca, lmap); +>lmap : Symbol(lmap, Decl(higherKindedTypesLift.ts, 76, 10)) +>lca : Symbol(lca, Decl(higherKindedTypesLift.ts, 76, 18)) +>fToLift : Symbol(fToLift, Decl(higherKindedTypesLift.ts, 75, 23)) +>lca : Symbol(lca, Decl(higherKindedTypesLift.ts, 76, 18)) +>lmap : Symbol(lmap, Decl(higherKindedTypesLift.ts, 76, 10)) +} + +function staticMap extends Functor<_T1, C1>, A1, B1>(fa1: C1, fmap1: (a1: A1) => B1): C1 { +>staticMap : Symbol(staticMap, Decl(higherKindedTypesLift.ts, 77, 1)) +>C1 : Symbol(C1, Decl(higherKindedTypesLift.ts, 79, 19)) +>_T1 : Symbol(_T1, Decl(higherKindedTypesLift.ts, 79, 22)) +>Functor : Symbol(Functor, Decl(higherKindedTypesLift.ts, 0, 54)) +>_T1 : Symbol(_T1, Decl(higherKindedTypesLift.ts, 79, 22)) +>C1 : Symbol(C1, Decl(higherKindedTypesLift.ts, 79, 19)) +>A1 : Symbol(A1, Decl(higherKindedTypesLift.ts, 79, 52)) +>B1 : Symbol(B1, Decl(higherKindedTypesLift.ts, 79, 56)) +>fa1 : Symbol(fa1, Decl(higherKindedTypesLift.ts, 79, 61)) +>C1 : Symbol(C1, Decl(higherKindedTypesLift.ts, 79, 19)) +>A1 : Symbol(A1, Decl(higherKindedTypesLift.ts, 79, 52)) +>fmap1 : Symbol(fmap1, Decl(higherKindedTypesLift.ts, 79, 73)) +>a1 : Symbol(a1, Decl(higherKindedTypesLift.ts, 79, 82)) +>A1 : Symbol(A1, Decl(higherKindedTypesLift.ts, 79, 52)) +>B1 : Symbol(B1, Decl(higherKindedTypesLift.ts, 79, 56)) +>C1 : Symbol(C1, Decl(higherKindedTypesLift.ts, 79, 19)) +>B1 : Symbol(B1, Decl(higherKindedTypesLift.ts, 79, 56)) + + return fa1.map(fmap1); +>fa1.map : Symbol(Functor.map, Decl(higherKindedTypesLift.ts, 2, 46)) +>fa1 : Symbol(fa1, Decl(higherKindedTypesLift.ts, 79, 61)) +>map : Symbol(Functor.map, Decl(higherKindedTypesLift.ts, 2, 46)) +>fmap1 : Symbol(fmap1, Decl(higherKindedTypesLift.ts, 79, 73)) +} + +const liftedFunctor1 = lift1(staticMap); +>liftedFunctor1 : Symbol(liftedFunctor1, Decl(higherKindedTypesLift.ts, 83, 5)) +>lift1 : Symbol(lift1, Decl(higherKindedTypesLift.ts, 60, 1)) +>staticMap : Symbol(staticMap, Decl(higherKindedTypesLift.ts, 77, 1)) + +const liftedFunctor2 = lift2(staticMap); +>liftedFunctor2 : Symbol(liftedFunctor2, Decl(higherKindedTypesLift.ts, 84, 5)) +>lift2 : Symbol(lift2, Decl(higherKindedTypesLift.ts, 64, 1)) +>staticMap : Symbol(staticMap, Decl(higherKindedTypesLift.ts, 77, 1)) + +const liftedFunctor3 = lift3(staticMap); +>liftedFunctor3 : Symbol(liftedFunctor3, Decl(higherKindedTypesLift.ts, 85, 5)) +>lift3 : Symbol(lift3, Decl(higherKindedTypesLift.ts, 72, 1)) +>staticMap : Symbol(staticMap, Decl(higherKindedTypesLift.ts, 77, 1)) + +const liftedStringLength1 = liftedFunctor1(stringLength); +>liftedStringLength1 : Symbol(liftedStringLength1, Decl(higherKindedTypesLift.ts, 87, 5)) +>liftedFunctor1 : Symbol(liftedFunctor1, Decl(higherKindedTypesLift.ts, 83, 5)) +>stringLength : Symbol(stringLength, Decl(higherKindedTypesLift.ts, 0, 0)) + +const liftedStringLength2 = liftedFunctor2(stringLength); +>liftedStringLength2 : Symbol(liftedStringLength2, Decl(higherKindedTypesLift.ts, 88, 5)) +>liftedFunctor2 : Symbol(liftedFunctor2, Decl(higherKindedTypesLift.ts, 84, 5)) +>stringLength : Symbol(stringLength, Decl(higherKindedTypesLift.ts, 0, 0)) + +const liftedStringLength3 = liftedFunctor3(stringLength); +>liftedStringLength3 : Symbol(liftedStringLength3, Decl(higherKindedTypesLift.ts, 89, 5)) +>liftedFunctor3 : Symbol(liftedFunctor3, Decl(higherKindedTypesLift.ts, 85, 5)) +>stringLength : Symbol(stringLength, Decl(higherKindedTypesLift.ts, 0, 0)) + + +const result1 = liftedStringLength1(functorXString); +>result1 : Symbol(result1, Decl(higherKindedTypesLift.ts, 92, 5)) +>liftedStringLength1 : Symbol(liftedStringLength1, Decl(higherKindedTypesLift.ts, 87, 5)) +>functorXString : Symbol(functorXString, Decl(higherKindedTypesLift.ts, 22, 5)) + +const expectedType1: FunctorX = result1; +>expectedType1 : Symbol(expectedType1, Decl(higherKindedTypesLift.ts, 93, 5)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) +>result1 : Symbol(result1, Decl(higherKindedTypesLift.ts, 92, 5)) + +const result2 = liftedStringLength2(functorXString); +>result2 : Symbol(result2, Decl(higherKindedTypesLift.ts, 94, 5)) +>liftedStringLength2 : Symbol(liftedStringLength2, Decl(higherKindedTypesLift.ts, 88, 5)) +>functorXString : Symbol(functorXString, Decl(higherKindedTypesLift.ts, 22, 5)) + +const expectedType2: FunctorX = result2; +>expectedType2 : Symbol(expectedType2, Decl(higherKindedTypesLift.ts, 95, 5)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) +>result2 : Symbol(result2, Decl(higherKindedTypesLift.ts, 94, 5)) + +const result3 = liftedStringLength3(functorXString); +>result3 : Symbol(result3, Decl(higherKindedTypesLift.ts, 96, 5)) +>liftedStringLength3 : Symbol(liftedStringLength3, Decl(higherKindedTypesLift.ts, 89, 5)) +>functorXString : Symbol(functorXString, Decl(higherKindedTypesLift.ts, 22, 5)) + +const expectedType3: FunctorX = result3; +>expectedType3 : Symbol(expectedType3, Decl(higherKindedTypesLift.ts, 97, 5)) +>FunctorX : Symbol(FunctorX, Decl(higherKindedTypesLift.ts, 8, 1)) +>result3 : Symbol(result3, Decl(higherKindedTypesLift.ts, 96, 5)) + +const expectErrorA1 = liftedStringLength1(result1); +>expectErrorA1 : Symbol(expectErrorA1, Decl(higherKindedTypesLift.ts, 99, 5)) +>liftedStringLength1 : Symbol(liftedStringLength1, Decl(higherKindedTypesLift.ts, 87, 5)) +>result1 : Symbol(result1, Decl(higherKindedTypesLift.ts, 92, 5)) + +const expectErrorA2 = liftedStringLength2(result2); +>expectErrorA2 : Symbol(expectErrorA2, Decl(higherKindedTypesLift.ts, 100, 5)) +>liftedStringLength2 : Symbol(liftedStringLength2, Decl(higherKindedTypesLift.ts, 88, 5)) +>result2 : Symbol(result2, Decl(higherKindedTypesLift.ts, 94, 5)) + +const expectErrorA3 = liftedStringLength3(result3); +>expectErrorA3 : Symbol(expectErrorA3, Decl(higherKindedTypesLift.ts, 101, 5)) +>liftedStringLength3 : Symbol(liftedStringLength3, Decl(higherKindedTypesLift.ts, 89, 5)) +>result3 : Symbol(result3, Decl(higherKindedTypesLift.ts, 96, 5)) + + +const stringArray = ["not explicitly declared to implement functor"]; +>stringArray : Symbol(stringArray, Decl(higherKindedTypesLift.ts, 104, 5)) + +const arrayResult1 = liftedStringLength1(stringArray); +>arrayResult1 : Symbol(arrayResult1, Decl(higherKindedTypesLift.ts, 105, 5)) +>liftedStringLength1 : Symbol(liftedStringLength1, Decl(higherKindedTypesLift.ts, 87, 5)) +>stringArray : Symbol(stringArray, Decl(higherKindedTypesLift.ts, 104, 5)) + +const arrayExpectedType1: Array = arrayResult1; +>arrayExpectedType1 : Symbol(arrayExpectedType1, Decl(higherKindedTypesLift.ts, 106, 5)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>arrayResult1 : Symbol(arrayResult1, Decl(higherKindedTypesLift.ts, 105, 5)) + +const arrayResult2 = liftedStringLength2(stringArray); +>arrayResult2 : Symbol(arrayResult2, Decl(higherKindedTypesLift.ts, 107, 5)) +>liftedStringLength2 : Symbol(liftedStringLength2, Decl(higherKindedTypesLift.ts, 88, 5)) +>stringArray : Symbol(stringArray, Decl(higherKindedTypesLift.ts, 104, 5)) + +const arrayExpectedType2: Array = arrayResult2; +>arrayExpectedType2 : Symbol(arrayExpectedType2, Decl(higherKindedTypesLift.ts, 108, 5)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>arrayResult2 : Symbol(arrayResult2, Decl(higherKindedTypesLift.ts, 107, 5)) + +const arrayResult3 = liftedStringLength3(stringArray); +>arrayResult3 : Symbol(arrayResult3, Decl(higherKindedTypesLift.ts, 109, 5)) +>liftedStringLength3 : Symbol(liftedStringLength3, Decl(higherKindedTypesLift.ts, 89, 5)) +>stringArray : Symbol(stringArray, Decl(higherKindedTypesLift.ts, 104, 5)) + +const arrayExpectedType3: Array = arrayResult3; +>arrayExpectedType3 : Symbol(arrayExpectedType3, Decl(higherKindedTypesLift.ts, 110, 5)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>arrayResult3 : Symbol(arrayResult3, Decl(higherKindedTypesLift.ts, 109, 5)) + +const arrayExpectErrorA1 = liftedStringLength1(arrayResult1); +>arrayExpectErrorA1 : Symbol(arrayExpectErrorA1, Decl(higherKindedTypesLift.ts, 112, 5)) +>liftedStringLength1 : Symbol(liftedStringLength1, Decl(higherKindedTypesLift.ts, 87, 5)) +>arrayResult1 : Symbol(arrayResult1, Decl(higherKindedTypesLift.ts, 105, 5)) + +const arrayExpectErrorA2 = liftedStringLength2(arrayResult2); +>arrayExpectErrorA2 : Symbol(arrayExpectErrorA2, Decl(higherKindedTypesLift.ts, 113, 5)) +>liftedStringLength2 : Symbol(liftedStringLength2, Decl(higherKindedTypesLift.ts, 88, 5)) +>arrayResult2 : Symbol(arrayResult2, Decl(higherKindedTypesLift.ts, 107, 5)) + +const arrayExpectErrorA3 = liftedStringLength3(arrayResult3); +>arrayExpectErrorA3 : Symbol(arrayExpectErrorA3, Decl(higherKindedTypesLift.ts, 114, 5)) +>liftedStringLength3 : Symbol(liftedStringLength3, Decl(higherKindedTypesLift.ts, 89, 5)) +>arrayResult3 : Symbol(arrayResult3, Decl(higherKindedTypesLift.ts, 109, 5)) + + + +// should have error because DiffFunctorY has diffMap function, not "map" as needed because liftedFunctor was created from staticMap which declared Functor +const expectErrorB1 = liftedStringLength1(diffFunctorYString); +>expectErrorB1 : Symbol(expectErrorB1, Decl(higherKindedTypesLift.ts, 119, 5)) +>liftedStringLength1 : Symbol(liftedStringLength1, Decl(higherKindedTypesLift.ts, 87, 5)) +>diffFunctorYString : Symbol(diffFunctorYString, Decl(higherKindedTypesLift.ts, 31, 13)) + +const expectErrorB2 = liftedStringLength2(diffFunctorYString); +>expectErrorB2 : Symbol(expectErrorB2, Decl(higherKindedTypesLift.ts, 120, 5)) +>liftedStringLength2 : Symbol(liftedStringLength2, Decl(higherKindedTypesLift.ts, 88, 5)) +>diffFunctorYString : Symbol(diffFunctorYString, Decl(higherKindedTypesLift.ts, 31, 13)) + +const expectErrorB3 = liftedStringLength3(diffFunctorYString); +>expectErrorB3 : Symbol(expectErrorB3, Decl(higherKindedTypesLift.ts, 121, 5)) +>liftedStringLength3 : Symbol(liftedStringLength3, Decl(higherKindedTypesLift.ts, 89, 5)) +>diffFunctorYString : Symbol(diffFunctorYString, Decl(higherKindedTypesLift.ts, 31, 13)) + + +const expectErrorC1 = liftedStringLength1(invalidFunctor); +>expectErrorC1 : Symbol(expectErrorC1, Decl(higherKindedTypesLift.ts, 124, 5)) +>liftedStringLength1 : Symbol(liftedStringLength1, Decl(higherKindedTypesLift.ts, 87, 5)) +>invalidFunctor : Symbol(invalidFunctor, Decl(higherKindedTypesLift.ts, 37, 13)) + +const expectErrorC2 = liftedStringLength2(invalidFunctor); +>expectErrorC2 : Symbol(expectErrorC2, Decl(higherKindedTypesLift.ts, 125, 5)) +>liftedStringLength2 : Symbol(liftedStringLength2, Decl(higherKindedTypesLift.ts, 88, 5)) +>invalidFunctor : Symbol(invalidFunctor, Decl(higherKindedTypesLift.ts, 37, 13)) + +const expectErrorC3 = liftedStringLength3(invalidFunctor); +>expectErrorC3 : Symbol(expectErrorC3, Decl(higherKindedTypesLift.ts, 126, 5)) +>liftedStringLength3 : Symbol(liftedStringLength3, Decl(higherKindedTypesLift.ts, 89, 5)) +>invalidFunctor : Symbol(invalidFunctor, Decl(higherKindedTypesLift.ts, 37, 13)) + + +const expectErrorD1 = liftedStringLength1(invalidFunctor2); +>expectErrorD1 : Symbol(expectErrorD1, Decl(higherKindedTypesLift.ts, 129, 5)) +>liftedStringLength1 : Symbol(liftedStringLength1, Decl(higherKindedTypesLift.ts, 87, 5)) +>invalidFunctor2 : Symbol(invalidFunctor2, Decl(higherKindedTypesLift.ts, 45, 13)) + +const expectErrorD2 = liftedStringLength2(invalidFunctor2); +>expectErrorD2 : Symbol(expectErrorD2, Decl(higherKindedTypesLift.ts, 130, 5)) +>liftedStringLength2 : Symbol(liftedStringLength2, Decl(higherKindedTypesLift.ts, 88, 5)) +>invalidFunctor2 : Symbol(invalidFunctor2, Decl(higherKindedTypesLift.ts, 45, 13)) + +const expectErrorD3 = liftedStringLength3(invalidFunctor2); +>expectErrorD3 : Symbol(expectErrorD3, Decl(higherKindedTypesLift.ts, 131, 5)) +>liftedStringLength3 : Symbol(liftedStringLength3, Decl(higherKindedTypesLift.ts, 89, 5)) +>invalidFunctor2 : Symbol(invalidFunctor2, Decl(higherKindedTypesLift.ts, 45, 13)) + diff --git a/tests/baselines/reference/higherKindedTypesLift.types b/tests/baselines/reference/higherKindedTypesLift.types new file mode 100644 index 0000000000000..9546d24a26629 --- /dev/null +++ b/tests/baselines/reference/higherKindedTypesLift.types @@ -0,0 +1,572 @@ +=== tests/cases/compiler/higherKindedTypesLift.ts === +declare function stringLength(strarg: string): number; +>stringLength : (strarg: string) => number +>strarg : string + +export interface Functor> { +>Functor : Functor> +>AF : AF +>Container : Container<_TF> +>_TF : _TF + + map(f: (a: AF) => BF): Container; +>map : (f: (a: AF) => BF) => Container +>BF : BF +>f : (a: AF) => BF +>a : AF +>AF : AF +>BF : BF +>Container : Container<_TF> +>BF : BF +} + +export interface DiffFunctor> { +>DiffFunctor : DiffFunctor> +>DA : DA +>DContainer : DContainer<_TD> +>_TD : _TD + + diffMap(df: (da: DA) => DB): DContainer; +>diffMap : (df: (da: DA) => DB) => DContainer +>DB : DB +>df : (da: DA) => DB +>da : DA +>DA : DA +>DB : DB +>DContainer : DContainer<_TD> +>DB : DB +} + +class FunctorX implements Functor { +>FunctorX : FunctorX +>AX : AX +>Functor : Functor> +>AX : AX +>FunctorX : FunctorX + + constructor(private elements: AX[]) {} +>elements : AX[] +>AX : AX + + map(f: (a: AX) => BX): FunctorX { +>map : (f: (a: AX) => BX) => FunctorX +>BX : BX +>f : (a: AX) => BX +>a : AX +>AX : AX +>BX : BX +>FunctorX : FunctorX +>BX : BX + + const mappedElements = this.elements.map(f); +>mappedElements : BX[] +>this.elements.map(f) : BX[] +>this.elements.map : (callbackfn: (value: AX, index: number, array: AX[]) => U, thisArg?: any) => U[] +>this.elements : AX[] +>this : this +>elements : AX[] +>map : (callbackfn: (value: AX, index: number, array: AX[]) => U, thisArg?: any) => U[] +>f : (a: AX) => BX + + return new FunctorX(mappedElements); +>new FunctorX(mappedElements) : FunctorX +>FunctorX : typeof FunctorX +>mappedElements : BX[] + } + + firstVal(): AX | undefined { +>firstVal : () => AX | undefined +>AX : AX + + return this.elements.length ? this.elements[0] : undefined; +>this.elements.length ? this.elements[0] : undefined : AX | undefined +>this.elements.length : number +>this.elements : AX[] +>this : this +>elements : AX[] +>length : number +>this.elements[0] : AX +>this.elements : AX[] +>this : this +>elements : AX[] +>0 : 0 +>undefined : undefined + + }; +} + +const functorXString = new FunctorX(["myFunctorX"]); +>functorXString : FunctorX +>new FunctorX(["myFunctorX"]) : FunctorX +>FunctorX : typeof FunctorX +>["myFunctorX"] : string[] +>"myFunctorX" : "myFunctorX" + +declare class DiffFunctorY implements DiffFunctor { +>DiffFunctorY : DiffFunctorY +>AY : AY +>DiffFunctor : DiffFunctor> +>AY : AY +>DiffFunctorY : DiffFunctorY + + diffMap(f: (a: AY) => BY): DiffFunctorY +>diffMap : (f: (a: AY) => BY) => DiffFunctorY +>BY : BY +>f : (a: AY) => BY +>a : AY +>AY : AY +>BY : BY +>DiffFunctorY : DiffFunctorY +>BY : BY + + firstValY(): AY | undefined +>firstValY : () => AY | undefined +>AY : AY +} + +declare const diffFunctorYString: DiffFunctorY; +>diffFunctorYString : DiffFunctorY +>DiffFunctorY : DiffFunctorY + +declare class InvalidFunctor { +>InvalidFunctor : InvalidFunctor +>IA : IA + + // does not actually implement Functor because it doesn't return InvalidFunctor + map(fi: (ia: IA) => IB): IB +>map : (fi: (ia: IA) => IB) => IB +>IB : IB +>fi : (ia: IA) => IB +>ia : IA +>IA : IA +>IB : IB +>IB : IB +} +declare const invalidFunctor: InvalidFunctor; +>invalidFunctor : InvalidFunctor +>InvalidFunctor : InvalidFunctor + +declare class InvalidFunctor2 { +>InvalidFunctor2 : InvalidFunctor2 +>IA2 : IA2 + + // does not actually implement Functor because it doesn't return InvalidFunctor2 + map(fi2: (ia2: IA2) => IB2): FunctorX +>map : (fi2: (ia2: IA2) => IB2) => FunctorX +>IB2 : IB2 +>fi2 : (ia2: IA2) => IB2 +>ia2 : IA2 +>IA2 : IA2 +>IB2 : IB2 +>FunctorX : FunctorX +>IB2 : IB2 + + someUniqueMethod(): IA2 +>someUniqueMethod : () => IA2 +>IA2 : IA2 +} +declare const invalidFunctor2: InvalidFunctor2; +>invalidFunctor2 : InvalidFunctor2 +>InvalidFunctor2 : InvalidFunctor2 + +interface StaticFunctor> { +>StaticFunctor : StaticFunctor> +>CS : CS<_TS> +>_TS : _TS + + (csas: CS, fmapstatic: (as: AS) => BS): CS; +>AS : AS +>BS : BS +>csas : CS +>CS : CS<_TS> +>AS : AS +>fmapstatic : (as: AS) => BS +>as : AS +>AS : AS +>BS : BS +>CS : CS<_TS> +>BS : BS +} + +interface LiftedResult> { +>LiftedResult : LiftedResult> +>LRC : LRC<_LT> +>_LT : _LT + + (lrmap: (lra: LRA) => LRB): extends LRC<_NT>>(lrclra: NC) => NC +>LRA : LRA +>LRB : LRB +>lrmap : (lra: LRA) => LRB +>lra : LRA +>LRA : LRA +>LRB : LRB +>NC : NC<_NT> +>_NT : _NT +>LRC : LRC<_LT> +>_NT : _NT +>lrclra : NC +>NC : NC<_NT> +>LRA : LRA +>NC : NC<_NT> +>LRB : LRB +} + +interface LiftedResult3A> { +>LiftedResult3A : LiftedResult3A> +>LRC : LRC<_LT> +>_LT : _LT + + (lrmap: (lra: LRA) => LRB): LiftedResult3B +>LRA : LRA +>LRB : LRB +>lrmap : (lra: LRA) => LRB +>lra : LRA +>LRA : LRA +>LRB : LRB +>LiftedResult3B : LiftedResult3B, LRA, LRB> +>LRC : LRC<_LT> +>LRA : LRA +>LRB : LRB +} +interface LiftedResult3B, LRA, LRB> { +>LiftedResult3B : LiftedResult3B, LRA, LRB> +>LRC : LRC<_LT> +>_LT : _LT +>LRA : LRA +>LRB : LRB + + extends LRC<_NT>>(lrclra: NC): NC +>NC : NC<_NT> +>_NT : _NT +>LRC : LRC<_LT> +>_NT : _NT +>lrclra : NC +>NC : NC<_NT> +>LRA : LRA +>NC : NC<_NT> +>LRB : LRB +} + +function lift1>(fToLift: StaticFunctor): LiftedResult { +>lift1 : (fToLift: StaticFunctor>) => LiftedResult> +>C : C<_TL> +>_TL : _TL +>fToLift : StaticFunctor> +>StaticFunctor : StaticFunctor> +>C : C<_TL> +>LiftedResult : LiftedResult> +>C : C<_TL> + + return lmap => lca => fToLift(lca, lmap); +>lmap => lca => fToLift(lca, lmap) : (lmap: (lra: LRA) => LRB) => >(lca: LiftedResult>.NC) => C +>lmap : (lra: LRA) => LRB +>lca => fToLift(lca, lmap) : >(lca: LiftedResult>.NC) => C +>lca : LiftedResult>.NC +>fToLift(lca, lmap) : C +>fToLift : StaticFunctor> +>lca : LiftedResult>.NC +>lmap : (lra: LRA) => LRB +} + +// lift2 does not use intermediate interfaces +function lift2>( +>lift2 : (fToLift: (csas: C, fmapstatic: (as: AS) => BS) => C) => (lrmap: (lra: LA) => LB) => >(lrclra: NC) => NC +>C : C<_TL> +>_TL : _TL + + fToLift: (csas: C, fmapstatic: (as: AS) => BS) => C +>fToLift : (csas: C, fmapstatic: (as: AS) => BS) => C +>AS : AS +>BS : BS +>csas : C +>C : C<_TL> +>AS : AS +>fmapstatic : (as: AS) => BS +>as : AS +>AS : AS +>BS : BS +>C : C<_TL> +>BS : BS + +): + (lrmap: (lra: LA) => LB) => extends C<_NT>>(lrclra: NC) => NC { +>LA : LA +>LB : LB +>lrmap : (lra: LA) => LB +>lra : LA +>LA : LA +>LB : LB +>NC : NC<_NT> +>_NT : _NT +>C : C<_TL> +>_NT : _NT +>lrclra : NC +>NC : NC<_NT> +>LA : LA +>NC : NC<_NT> +>LB : LB + + return lmap => lca => fToLift(lca, lmap); +>lmap => lca => fToLift(lca, lmap) : (lmap: (lra: LA) => LB) => >(lca: NC) => C +>lmap : (lra: LA) => LB +>lca => fToLift(lca, lmap) : >(lca: NC) => C +>lca : NC +>fToLift(lca, lmap) : C +>fToLift : (csas: C, fmapstatic: (as: AS) => BS) => C +>lca : NC +>lmap : (lra: LA) => LB +} + +// lift3 uses an extra intermediate interface +function lift3>(fToLift: StaticFunctor): LiftedResult3A { +>lift3 : (fToLift: StaticFunctor>) => LiftedResult3A> +>C : C<_TL> +>_TL : _TL +>fToLift : StaticFunctor> +>StaticFunctor : StaticFunctor> +>C : C<_TL> +>LiftedResult3A : LiftedResult3A> +>C : C<_TL> + + return lmap => lca => fToLift(lca, lmap); +>lmap => lca => fToLift(lca, lmap) : (lmap: (lra: LRA) => LRB) => >(lca: LiftedResult3B>.NC) => C +>lmap : (lra: LRA) => LRB +>lca => fToLift(lca, lmap) : >(lca: LiftedResult3B>.NC) => C +>lca : LiftedResult3B>.NC +>fToLift(lca, lmap) : C +>fToLift : StaticFunctor> +>lca : LiftedResult3B>.NC +>lmap : (lra: LRA) => LRB +} + +function staticMap extends Functor<_T1, C1>, A1, B1>(fa1: C1, fmap1: (a1: A1) => B1): C1 { +>staticMap : >, A1, B1>(fa1: C1, fmap1: (a1: A1) => B1) => C1 +>C1 : C1<_T1> +>_T1 : _T1 +>Functor : Functor> +>_T1 : _T1 +>C1 : C1<_T1> +>A1 : A1 +>B1 : B1 +>fa1 : C1 +>C1 : C1<_T1> +>A1 : A1 +>fmap1 : (a1: A1) => B1 +>a1 : A1 +>A1 : A1 +>B1 : B1 +>C1 : C1<_T1> +>B1 : B1 + + return fa1.map(fmap1); +>fa1.map(fmap1) : C1 +>fa1.map : (f: (a: A1) => BF) => C1 +>fa1 : C1 +>map : (f: (a: A1) => BF) => C1 +>fmap1 : (a1: A1) => B1 +} + +const liftedFunctor1 = lift1(staticMap); +>liftedFunctor1 : LiftedResult> +>lift1(staticMap) : LiftedResult> +>lift1 : (fToLift: StaticFunctor>) => LiftedResult> +>staticMap : >, A1, B1>(fa1: C1, fmap1: (a1: A1) => B1) => C1 + +const liftedFunctor2 = lift2(staticMap); +>liftedFunctor2 : (lrmap: (lra: LA) => LB) => >(lrclra: lift2>.NC) => lift2>.NC +>lift2(staticMap) : (lrmap: (lra: LA) => LB) => >(lrclra: lift2>.NC) => lift2>.NC +>lift2 : (fToLift: (csas: C, fmapstatic: (as: AS) => BS) => C) => (lrmap: (lra: LA) => LB) => >(lrclra: NC) => NC +>staticMap : >, A1, B1>(fa1: C1, fmap1: (a1: A1) => B1) => C1 + +const liftedFunctor3 = lift3(staticMap); +>liftedFunctor3 : LiftedResult3A> +>lift3(staticMap) : LiftedResult3A> +>lift3 : (fToLift: StaticFunctor>) => LiftedResult3A> +>staticMap : >, A1, B1>(fa1: C1, fmap1: (a1: A1) => B1) => C1 + +const liftedStringLength1 = liftedFunctor1(stringLength); +>liftedStringLength1 : >(lrclra: LiftedResult>.NC) => LiftedResult>.NC +>liftedFunctor1(stringLength) : >(lrclra: LiftedResult>.NC) => LiftedResult>.NC +>liftedFunctor1 : LiftedResult> +>stringLength : (strarg: string) => number + +const liftedStringLength2 = liftedFunctor2(stringLength); +>liftedStringLength2 : >(lrclra: lift2>.NC) => lift2>.NC +>liftedFunctor2(stringLength) : >(lrclra: lift2>.NC) => lift2>.NC +>liftedFunctor2 : (lrmap: (lra: LA) => LB) => >(lrclra: lift2>.NC) => lift2>.NC +>stringLength : (strarg: string) => number + +const liftedStringLength3 = liftedFunctor3(stringLength); +>liftedStringLength3 : LiftedResult3B, string, number> +>liftedFunctor3(stringLength) : LiftedResult3B, string, number> +>liftedFunctor3 : LiftedResult3A> +>stringLength : (strarg: string) => number + + +const result1 = liftedStringLength1(functorXString); +>result1 : FunctorX +>liftedStringLength1(functorXString) : FunctorX +>liftedStringLength1 : >(lrclra: LiftedResult>.NC) => LiftedResult>.NC +>functorXString : FunctorX + +const expectedType1: FunctorX = result1; +>expectedType1 : FunctorX +>FunctorX : FunctorX +>result1 : FunctorX + +const result2 = liftedStringLength2(functorXString); +>result2 : FunctorX +>liftedStringLength2(functorXString) : FunctorX +>liftedStringLength2 : >(lrclra: lift2>.NC) => lift2>.NC +>functorXString : FunctorX + +const expectedType2: FunctorX = result2; +>expectedType2 : FunctorX +>FunctorX : FunctorX +>result2 : FunctorX + +const result3 = liftedStringLength3(functorXString); +>result3 : FunctorX +>liftedStringLength3(functorXString) : FunctorX +>liftedStringLength3 : LiftedResult3B, string, number> +>functorXString : FunctorX + +const expectedType3: FunctorX = result3; +>expectedType3 : FunctorX +>FunctorX : FunctorX +>result3 : FunctorX + +const expectErrorA1 = liftedStringLength1(result1); +>expectErrorA1 : any +>liftedStringLength1(result1) : any +>liftedStringLength1 : >(lrclra: LiftedResult>.NC) => LiftedResult>.NC +>result1 : FunctorX + +const expectErrorA2 = liftedStringLength2(result2); +>expectErrorA2 : any +>liftedStringLength2(result2) : any +>liftedStringLength2 : >(lrclra: lift2>.NC) => lift2>.NC +>result2 : FunctorX + +const expectErrorA3 = liftedStringLength3(result3); +>expectErrorA3 : any +>liftedStringLength3(result3) : any +>liftedStringLength3 : LiftedResult3B, string, number> +>result3 : FunctorX + + +const stringArray = ["not explicitly declared to implement functor"]; +>stringArray : string[] +>["not explicitly declared to implement functor"] : string[] +>"not explicitly declared to implement functor" : "not explicitly declared to implement functor" + +const arrayResult1 = liftedStringLength1(stringArray); +>arrayResult1 : number[] +>liftedStringLength1(stringArray) : number[] +>liftedStringLength1 : >(lrclra: LiftedResult>.NC) => LiftedResult>.NC +>stringArray : string[] + +const arrayExpectedType1: Array = arrayResult1; +>arrayExpectedType1 : number[] +>Array : T[] +>arrayResult1 : number[] + +const arrayResult2 = liftedStringLength2(stringArray); +>arrayResult2 : number[] +>liftedStringLength2(stringArray) : number[] +>liftedStringLength2 : >(lrclra: lift2>.NC) => lift2>.NC +>stringArray : string[] + +const arrayExpectedType2: Array = arrayResult2; +>arrayExpectedType2 : number[] +>Array : T[] +>arrayResult2 : number[] + +const arrayResult3 = liftedStringLength3(stringArray); +>arrayResult3 : number[] +>liftedStringLength3(stringArray) : number[] +>liftedStringLength3 : LiftedResult3B, string, number> +>stringArray : string[] + +const arrayExpectedType3: Array = arrayResult3; +>arrayExpectedType3 : number[] +>Array : T[] +>arrayResult3 : number[] + +const arrayExpectErrorA1 = liftedStringLength1(arrayResult1); +>arrayExpectErrorA1 : any +>liftedStringLength1(arrayResult1) : any +>liftedStringLength1 : >(lrclra: LiftedResult>.NC) => LiftedResult>.NC +>arrayResult1 : number[] + +const arrayExpectErrorA2 = liftedStringLength2(arrayResult2); +>arrayExpectErrorA2 : any +>liftedStringLength2(arrayResult2) : any +>liftedStringLength2 : >(lrclra: lift2>.NC) => lift2>.NC +>arrayResult2 : number[] + +const arrayExpectErrorA3 = liftedStringLength3(arrayResult3); +>arrayExpectErrorA3 : any +>liftedStringLength3(arrayResult3) : any +>liftedStringLength3 : LiftedResult3B, string, number> +>arrayResult3 : number[] + + + +// should have error because DiffFunctorY has diffMap function, not "map" as needed because liftedFunctor was created from staticMap which declared Functor +const expectErrorB1 = liftedStringLength1(diffFunctorYString); +>expectErrorB1 : any +>liftedStringLength1(diffFunctorYString) : any +>liftedStringLength1 : >(lrclra: LiftedResult>.NC) => LiftedResult>.NC +>diffFunctorYString : DiffFunctorY + +const expectErrorB2 = liftedStringLength2(diffFunctorYString); +>expectErrorB2 : any +>liftedStringLength2(diffFunctorYString) : any +>liftedStringLength2 : >(lrclra: lift2>.NC) => lift2>.NC +>diffFunctorYString : DiffFunctorY + +const expectErrorB3 = liftedStringLength3(diffFunctorYString); +>expectErrorB3 : any +>liftedStringLength3(diffFunctorYString) : any +>liftedStringLength3 : LiftedResult3B, string, number> +>diffFunctorYString : DiffFunctorY + + +const expectErrorC1 = liftedStringLength1(invalidFunctor); +>expectErrorC1 : any +>liftedStringLength1(invalidFunctor) : any +>liftedStringLength1 : >(lrclra: LiftedResult>.NC) => LiftedResult>.NC +>invalidFunctor : InvalidFunctor + +const expectErrorC2 = liftedStringLength2(invalidFunctor); +>expectErrorC2 : any +>liftedStringLength2(invalidFunctor) : any +>liftedStringLength2 : >(lrclra: lift2>.NC) => lift2>.NC +>invalidFunctor : InvalidFunctor + +const expectErrorC3 = liftedStringLength3(invalidFunctor); +>expectErrorC3 : any +>liftedStringLength3(invalidFunctor) : any +>liftedStringLength3 : LiftedResult3B, string, number> +>invalidFunctor : InvalidFunctor + + +const expectErrorD1 = liftedStringLength1(invalidFunctor2); +>expectErrorD1 : any +>liftedStringLength1(invalidFunctor2) : any +>liftedStringLength1 : >(lrclra: LiftedResult>.NC) => LiftedResult>.NC +>invalidFunctor2 : InvalidFunctor2 + +const expectErrorD2 = liftedStringLength2(invalidFunctor2); +>expectErrorD2 : any +>liftedStringLength2(invalidFunctor2) : any +>liftedStringLength2 : >(lrclra: lift2>.NC) => lift2>.NC +>invalidFunctor2 : InvalidFunctor2 + +const expectErrorD3 = liftedStringLength3(invalidFunctor2); +>expectErrorD3 : any +>liftedStringLength3(invalidFunctor2) : any +>liftedStringLength3 : LiftedResult3B, string, number> +>invalidFunctor2 : InvalidFunctor2 + diff --git a/tests/cases/compiler/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts b/tests/cases/compiler/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts new file mode 100644 index 0000000000000..4dcbecc2d23b0 --- /dev/null +++ b/tests/cases/compiler/getBaseSignatureShouldNotGetWrapperTypeOfPrimitives.ts @@ -0,0 +1,38 @@ +// @strict: true + +export declare function f1(cb: (x: S) => T): T; +export declare function f2(cb: (x: S) => T): T; +export declare function f3(cb: (x: S) => T): T; +export declare function f4(cb: (x: S) => T): T; +export declare function f5(cb: (x: S) => T, obj: O): keyof O; +export declare function f6(cb: (x: S) => T, obj: O): T; +export declare function f7(cb: >(x: S) => T, obj: O): T; + +const x1 = f1(x => x); +const expectedx1: number = x1; + +let x2 = f2(x => x); +const expectedx2: string = x2; + +let x3 = f3(x => x); +const expectedx3: symbol = x3; + +let x4 = f4(x => x); +const expectedx4: number | string | symbol = x4; + +declare const symProp: unique symbol +declare const obj: { + prop: string, + [symProp]: symbol, + [index: number]: number +} + + +let x5 = f5((x) => x, obj); +const expectedx5: number | string | symbol = x5; + +let x6 = f6(x => x, obj); +const expectedx6: string = x6; + +let x7 = f7(x => x, obj); +const expectedx7: string = x7; \ No newline at end of file diff --git a/tests/cases/compiler/higherKindedTypes.ts b/tests/cases/compiler/higherKindedTypes.ts new file mode 100644 index 0000000000000..9d6bc60aca3bf --- /dev/null +++ b/tests/cases/compiler/higherKindedTypes.ts @@ -0,0 +1,60 @@ +// @strict: true + + + +interface Functor> { + map(f: (a: A) => B): Container; +} + +interface FunctorX extends Functor { + map(f: (a: A) => B): FunctorX; + xVal: string; +} + +interface FunctorY extends Functor { + map(f: (a: A) => B): FunctorY; + yVal: A; +} + +declare const initialX: FunctorX; +declare const initialY: FunctorY; + +const resultX1 = initialX.map(val => val.length); +const expectX1: FunctorX = resultX1; + +const resultY1 = initialY.map(val => val.length); +const expectY1: FunctorY = resultY1; + +const resultX2 = initialX.map(val => [val]); +const expectX2: FunctorX = resultX2; + +const resultY2 = initialY.map(val => [val]); +const expectY2: FunctorY = resultY2; + + +function staticMap extends Functor<_T, F>, A, B>(fa: F, f: (a: A) => B): F { + const result = fa.map(f); + return result; +} + +function staticMapBadImplementation extends Functor<_T, F>, A, B>(fa: F, f: (a: A) => B): F { + return fa; +} + +function staticMapNoConstraint, A, B>(fa: F, f: (a: A) => B): F { + // expect error here since F has no constraint so we have no idea what shape it will be + const result = fa.map(f); + return result; +} + +const resultX3 = staticMap(initialX, val => val.length); +const expectX3: FunctorX = resultX3; + +const resultY3 = staticMap(initialY, val => val.length); +const expectY3: FunctorY = resultY3; + +const resultX4 = staticMap(initialX, val => [val]); +const expectX4: FunctorX = resultX4; + +const resultY4 = staticMap(initialY, val => [val]); +const expectY4: FunctorY = resultY4; diff --git a/tests/cases/compiler/higherKindedTypesExpectedErrors.ts b/tests/cases/compiler/higherKindedTypesExpectedErrors.ts new file mode 100644 index 0000000000000..77c30beb60e08 --- /dev/null +++ b/tests/cases/compiler/higherKindedTypesExpectedErrors.ts @@ -0,0 +1,9 @@ +interface Functor, AX> { + map(fmapx: (fmapxax: AX) => BX): FX; +} + +// Expect error since array doesn't have xVal property +interface FunctorX extends Functor { + map(f: (a: A) => B): Array; + xVal: string; +} diff --git a/tests/cases/compiler/higherKindedTypesLift.ts b/tests/cases/compiler/higherKindedTypesLift.ts new file mode 100644 index 0000000000000..26840b7e2a7c7 --- /dev/null +++ b/tests/cases/compiler/higherKindedTypesLift.ts @@ -0,0 +1,134 @@ +// @strict: true + +declare function stringLength(strarg: string): number; + +export interface Functor> { + map(f: (a: AF) => BF): Container; +} + +export interface DiffFunctor> { + diffMap(df: (da: DA) => DB): DContainer; +} + +class FunctorX implements Functor { + constructor(private elements: AX[]) {} + map(f: (a: AX) => BX): FunctorX { + const mappedElements = this.elements.map(f); + return new FunctorX(mappedElements); + } + + firstVal(): AX | undefined { + return this.elements.length ? this.elements[0] : undefined; + }; +} + +const functorXString = new FunctorX(["myFunctorX"]); + +declare class DiffFunctorY implements DiffFunctor { + + diffMap(f: (a: AY) => BY): DiffFunctorY + + firstValY(): AY | undefined +} + +declare const diffFunctorYString: DiffFunctorY; + +declare class InvalidFunctor { + // does not actually implement Functor because it doesn't return InvalidFunctor + map(fi: (ia: IA) => IB): IB +} +declare const invalidFunctor: InvalidFunctor; + +declare class InvalidFunctor2 { + // does not actually implement Functor because it doesn't return InvalidFunctor2 + map(fi2: (ia2: IA2) => IB2): FunctorX + + someUniqueMethod(): IA2 +} +declare const invalidFunctor2: InvalidFunctor2; + +interface StaticFunctor> { + (csas: CS, fmapstatic: (as: AS) => BS): CS; +} + +interface LiftedResult> { + (lrmap: (lra: LRA) => LRB): extends LRC<_NT>>(lrclra: NC) => NC +} + +interface LiftedResult3A> { + (lrmap: (lra: LRA) => LRB): LiftedResult3B +} +interface LiftedResult3B, LRA, LRB> { + extends LRC<_NT>>(lrclra: NC): NC +} + +function lift1>(fToLift: StaticFunctor): LiftedResult { + return lmap => lca => fToLift(lca, lmap); +} + +// lift2 does not use intermediate interfaces +function lift2>( + fToLift: (csas: C, fmapstatic: (as: AS) => BS) => C +): + (lrmap: (lra: LA) => LB) => extends C<_NT>>(lrclra: NC) => NC { + return lmap => lca => fToLift(lca, lmap); +} + +// lift3 uses an extra intermediate interface +function lift3>(fToLift: StaticFunctor): LiftedResult3A { + return lmap => lca => fToLift(lca, lmap); +} + +function staticMap extends Functor<_T1, C1>, A1, B1>(fa1: C1, fmap1: (a1: A1) => B1): C1 { + return fa1.map(fmap1); +} + +const liftedFunctor1 = lift1(staticMap); +const liftedFunctor2 = lift2(staticMap); +const liftedFunctor3 = lift3(staticMap); + +const liftedStringLength1 = liftedFunctor1(stringLength); +const liftedStringLength2 = liftedFunctor2(stringLength); +const liftedStringLength3 = liftedFunctor3(stringLength); + + +const result1 = liftedStringLength1(functorXString); +const expectedType1: FunctorX = result1; +const result2 = liftedStringLength2(functorXString); +const expectedType2: FunctorX = result2; +const result3 = liftedStringLength3(functorXString); +const expectedType3: FunctorX = result3; + +const expectErrorA1 = liftedStringLength1(result1); +const expectErrorA2 = liftedStringLength2(result2); +const expectErrorA3 = liftedStringLength3(result3); + + +const stringArray = ["not explicitly declared to implement functor"]; +const arrayResult1 = liftedStringLength1(stringArray); +const arrayExpectedType1: Array = arrayResult1; +const arrayResult2 = liftedStringLength2(stringArray); +const arrayExpectedType2: Array = arrayResult2; +const arrayResult3 = liftedStringLength3(stringArray); +const arrayExpectedType3: Array = arrayResult3; + +const arrayExpectErrorA1 = liftedStringLength1(arrayResult1); +const arrayExpectErrorA2 = liftedStringLength2(arrayResult2); +const arrayExpectErrorA3 = liftedStringLength3(arrayResult3); + + + +// should have error because DiffFunctorY has diffMap function, not "map" as needed because liftedFunctor was created from staticMap which declared Functor +const expectErrorB1 = liftedStringLength1(diffFunctorYString); +const expectErrorB2 = liftedStringLength2(diffFunctorYString); +const expectErrorB3 = liftedStringLength3(diffFunctorYString); + + +const expectErrorC1 = liftedStringLength1(invalidFunctor); +const expectErrorC2 = liftedStringLength2(invalidFunctor); +const expectErrorC3 = liftedStringLength3(invalidFunctor); + + +const expectErrorD1 = liftedStringLength1(invalidFunctor2); +const expectErrorD2 = liftedStringLength2(invalidFunctor2); +const expectErrorD3 = liftedStringLength3(invalidFunctor2);