diff --git a/Herebyfile.mjs b/Herebyfile.mjs index 13adbec22e046..6fa5efe47e2bf 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -173,7 +173,7 @@ function createBundler(entrypoint, outfile, taskOptions = {}) { bundle: true, outfile, platform: "node", - target: "es2018", + target: "es2020", format: "cjs", sourcemap: "linked", sourcesContent: false, diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4c1ad31d43ff6..6ac5117d47caf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -801,6 +801,7 @@ import { NamespaceExportDeclaration, NamespaceImport, needsScopeMarker, + NeverWithErrorType, NewExpression, Node, NodeArray, @@ -851,6 +852,7 @@ import { PlusToken, PostfixUnaryExpression, PrefixUnaryExpression, + PrintType, PrivateIdentifier, Program, PromiseOrAwaitableType, @@ -890,6 +892,7 @@ import { SatisfiesExpression, ScriptKind, ScriptTarget, + SelfedType, SetAccessorDeclaration, setCommentRange, setEmitFlags, @@ -1298,14 +1301,18 @@ const enum IntrinsicTypeKind { Uppercase, Lowercase, Capitalize, - Uncapitalize + Uncapitalize, + Never, + Print } const intrinsicTypeKinds: ReadonlyMap = new Map(getEntries({ Uppercase: IntrinsicTypeKind.Uppercase, Lowercase: IntrinsicTypeKind.Lowercase, Capitalize: IntrinsicTypeKind.Capitalize, - Uncapitalize: IntrinsicTypeKind.Uncapitalize + Uncapitalize: IntrinsicTypeKind.Uncapitalize, + Never: IntrinsicTypeKind.Never, + Print: IntrinsicTypeKind.Print })); const SymbolLinks = class implements SymbolLinks { @@ -1828,6 +1835,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const evolvingArrayTypes: EvolvingArrayType[] = []; const undefinedProperties: SymbolTable = new Map(); const markerTypes = new Set(); + const neverWithErrorTypes = new Map(); + const printTypes = new Map(); const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String); const resolvingSymbol = createSymbol(0, InternalSymbolName.Resolving); @@ -3575,7 +3584,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isPrimitiveTypeName(name: __String) { - return name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never" || name === "unknown"; + return name === "any" || name === "string" || name === "number" || name === "boolean" || name === "never" || name === "unknown" || name === "self"; } function checkAndReportErrorForExportingPrimitiveType(errorLocation: Node, name: __String): boolean { @@ -6033,7 +6042,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } - function typeToString(type: Type, enclosingDeclaration?: Node, flags: TypeFormatFlags = TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope, writer: EmitTextWriter = createTextWriter("")): string { + function typeToString(type: Type, enclosingDeclaration?: Node, flags: TypeFormatFlags = getTypeToStringDefaultFlags(), writer: EmitTextWriter = createTextWriter("")): string { const noTruncation = compilerOptions.noErrorTruncation || flags & TypeFormatFlags.NoTruncation; const typeNode = nodeBuilder.typeToTypeNode(type, enclosingDeclaration, toNodeBuilderFlags(flags) | NodeBuilderFlags.IgnoreErrors | (noTruncation ? NodeBuilderFlags.NoTruncation : 0)); if (typeNode === undefined) return Debug.fail("should always get typenode"); @@ -6052,6 +6061,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return result; } + function getTypeToStringDefaultFlags() { + return TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope; + } + function getTypeNamesForErrorDisplay(left: Type, right: Type): [string, string] { let leftStr = symbolValueDeclarationIsContextSensitive(left.symbol) ? typeToString(left, left.symbol.valueDeclaration) : typeToString(left); let rightStr = symbolValueDeclarationIsContextSensitive(right.symbol) ? typeToString(right, right.symbol.valueDeclaration) : typeToString(right); @@ -6187,6 +6200,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (type.flags & TypeFlags.Unknown) { return factory.createKeywordTypeNode(SyntaxKind.UnknownKeyword); } + if (type.flags & TypeFlags.Self) { + return factory.createKeywordTypeNode(SyntaxKind.SelfKeyword); + } if (type.flags & TypeFlags.String) { context.approximateLength += 6; return factory.createKeywordTypeNode(SyntaxKind.StringKeyword); @@ -6232,7 +6248,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (type.flags & TypeFlags.StringLiteral) { context.approximateLength += ((type as StringLiteralType).value.length + 2); - return factory.createLiteralTypeNode(setEmitFlags(factory.createStringLiteral((type as StringLiteralType).value, !!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType)), EmitFlags.NoAsciiEscaping)); + return factory.createLiteralTypeNode(setEmitFlags( + factory.createStringLiteral((type as StringLiteralType).value, !!(context.flags & NodeBuilderFlags.UseSingleQuotesForStringLiteralType)), + EmitFlags.NoAsciiEscaping | (context.flags & NodeBuilderFlags.NoStringLiteralEscaping ? EmitFlags.NoStringEscaping : 0) + )); } if (type.flags & TypeFlags.NumberLiteral) { const value = (type as NumberLiteralType).value; @@ -6374,8 +6393,37 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return factory.createTypeOperatorNode(SyntaxKind.KeyOfKeyword, indexTypeNode); } if (type.flags & TypeFlags.TemplateLiteral) { - const texts = (type as TemplateLiteralType).texts; - const types = (type as TemplateLiteralType).types; + let texts = [...(type as TemplateLiteralType).texts]; + let types = [...(type as TemplateLiteralType).types]; + + const textOrTypes = flatMap(texts, (text, i) => [ + { kind: "text" as const, value: text }, + ...(types[i] ? [{ kind: "type" as const, value: types[i] }] : []) + ]); + + texts = []; + types = []; + for (let i = 0; i < textOrTypes.length;) { + const element = textOrTypes[i]; + if (element.kind === "type" && element.value.flags & TypeFlags.Print) { + element.value = getStringLiteralTypeFromPrintType(element.value as PrintType); + } + + if (element.kind === "type" && element.value.flags & TypeFlags.StringLiteral) { + texts[texts.length - 1] += (element.value as StringLiteralType).value + (textOrTypes[i+1].value as string); + i += 2; + continue; + } + + if (element.kind === "text") texts.push(element.value); + if (element.kind === "type") types.push(element.value); + i++; + } + + if (types.length === 0) { + return typeToTypeNodeHelper(getStringLiteralType(texts.join("")), context); + } + const templateHead = factory.createTemplateHead(texts[0]); const templateSpans = factory.createNodeArray( map(types, (t, i) => factory.createTemplateLiteralTypeSpan( @@ -6388,6 +6436,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const typeNode = typeToTypeNodeHelper((type as StringMappingType).type, context); return symbolToTypeNode((type as StringMappingType).symbol, context, SymbolFlags.Type, [typeNode]); } + if (type.flags & TypeFlags.Print) { + // TODO: if type has some type parameters return `Print<${T}>` instead of `${Print}` + return typeToTypeNodeHelper(getStringLiteralTypeFromPrintType(type as PrintType), context); + } if (type.flags & TypeFlags.IndexedAccess) { const objectTypeNode = typeToTypeNodeHelper((type as IndexedAccessType).objectType, context); const indexTypeNode = typeToTypeNodeHelper((type as IndexedAccessType).indexType, context); @@ -6400,6 +6452,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (type.flags & TypeFlags.Substitution) { return typeToTypeNodeHelper((type as SubstitutionType).baseType, context); } + if (type.flags & TypeFlags.Selfed) { + return typeToTypeNodeHelper((type as SelfedType).type, context); + } return Debug.fail("Should be unreachable."); @@ -9504,7 +9559,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function formatUnionTypes(types: readonly Type[]): Type[] { const result: Type[] = []; - let flags = 0 as TypeFlags; + let flags = 0n as TypeFlags; for (let i = 0; i < types.length; i++) { const t = types[i]; flags |= t.flags; @@ -9891,7 +9946,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isTypeAny(type: Type | undefined) { - return type && (type.flags & TypeFlags.Any) !== 0; + return type && (type.flags & TypeFlags.Any) !== 0n; } function isErrorType(type: Type) { @@ -11267,6 +11322,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Return the outer type parameters of a node or undefined if the node has no outer type parameters. function getOuterTypeParameters(node: Node, includeThisTypes?: boolean): TypeParameter[] | undefined { while (true) { + if (!node) { + return undefined; + } node = node.parent; // TODO: GH#18217 Use SourceFile kind check instead if (node && isBinaryExpression(node)) { // prototype assignments get the outer type parameters of their constructor function @@ -11309,11 +11367,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else if (node.kind === SyntaxKind.ConditionalType) { return concatenate(outerTypeParameters, getInferTypeParameters(node as ConditionalTypeNode)); } - const outerAndOwnTypeParameters = appendTypeParameters(outerTypeParameters, getEffectiveTypeParameterDeclarations(node as DeclarationWithTypeParameters)); + const outerAndOwnTypeParameters = + appendTypeParameters(outerTypeParameters, getEffectiveTypeParameterDeclarations(node as DeclarationWithTypeParameters)); + const thisType = includeThisTypes && (node.kind === SyntaxKind.ClassDeclaration || node.kind === SyntaxKind.ClassExpression || node.kind === SyntaxKind.InterfaceDeclaration || isJSConstructor(node)) && getDeclaredTypeOfClassOrInterface(getSymbolOfDeclaration(node as ClassLikeDeclaration | InterfaceDeclaration)).thisType; - return thisType ? append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; + + const selfType = + node.kind === SyntaxKind.TypeAliasDeclaration ? getSymbolLinks(getSymbolOfDeclaration(node as TypeAliasDeclaration)).selfType : undefined; + + const implicitTypeParameters = [ + ...(thisType ? [thisType] : []), + ...(selfType ? [selfType] : []) + ]; + + return concatenate(outerAndOwnTypeParameters, implicitTypeParameters); } case SyntaxKind.JSDocParameterTag: const paramSymbol = getParameterSymbolFromJSDoc(node as JSDocParameterTag); @@ -11719,6 +11788,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // If typeNode is missing, we will error in checkJSDocTypedefTag. let type = typeNode ? getTypeFromTypeNode(typeNode) : errorType; + const containsSelfType = !!forEachChildRecursively(declaration, node => { + if (node.kind === SyntaxKind.SelfKeyword) return true; + }); + if (containsSelfType) { + type = createSelfedType(type, links.selfType!); + } + if (popTypeResolution()) { const typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); if (typeParameters) { @@ -11846,6 +11922,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case SyntaxKind.UndefinedKeyword: case SyntaxKind.NeverKeyword: case SyntaxKind.LiteralType: + case SyntaxKind.SelfKeyword: return true; case SyntaxKind.ArrayType: return isThislessType((node as ArrayTypeNode).elementType); @@ -13329,7 +13406,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function getBaseConstraintOfType(type: Type): Type | undefined { - if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral | TypeFlags.StringMapping)) { + if (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.UnionOrIntersection | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print)) { const constraint = getResolvedBaseConstraint(type as InstantiableType | UnionOrIntersectionType); return constraint !== noConstraintType && constraint !== circularConstraintType ? constraint : undefined; } @@ -13442,6 +13519,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const constraint = getBaseConstraint((t as StringMappingType).type); return constraint && constraint !== (t as StringMappingType).type ? getStringMappingType((t as StringMappingType).symbol, constraint) : stringType; } + if (t.flags & TypeFlags.Print) { + return stringType; + } if (t.flags & TypeFlags.IndexedAccess) { if (isMappedTypeGenericIndexedAccess(t)) { // For indexed access types of the form { [P in K]: E }[X], where K is non-generic and X is generic, @@ -13460,6 +13540,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (t.flags & TypeFlags.Substitution) { return getBaseConstraint(getSubstitutionIntersection(t as SubstitutionType)); } + if (t.flags & TypeFlags.Selfed) { + return getBaseConstraint((t as SelfedType).type); + } return t; } } @@ -14858,17 +14941,31 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getTypeAliasInstantiation(symbol: Symbol, typeArguments: readonly Type[] | undefined, aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[]): Type { const type = getDeclaredTypeOfSymbol(symbol); - if (type === intrinsicMarkerType && intrinsicTypeKinds.has(symbol.escapedName as string) && typeArguments && typeArguments.length === 1) { - return getStringMappingType(symbol, typeArguments[0]); + if (type === intrinsicMarkerType && intrinsicTypeKinds.has(symbol.escapedName as string) && typeArguments && typeArguments.length >= 1) { + switch(intrinsicTypeKinds.get(symbol.escapedName as string)) { + case IntrinsicTypeKind.Lowercase: + case IntrinsicTypeKind.Uppercase: + case IntrinsicTypeKind.Capitalize: + case IntrinsicTypeKind.Uncapitalize: + return getStringMappingType(symbol, typeArguments[0]); + + case IntrinsicTypeKind.Never: + return createNeverWithErrorType(typeArguments[0]); + + case IntrinsicTypeKind.Print: + return createPrintType(typeArguments[0], typeArguments[1]); + } } + const links = getSymbolLinks(symbol); const typeParameters = links.typeParameters!; const id = getTypeListId(typeArguments) + getAliasId(aliasSymbol, aliasTypeArguments); let instantiation = links.instantiations!.get(id); if (!instantiation) { - links.instantiations!.set(id, instantiation = instantiateTypeWithAlias(type, - createTypeMapper(typeParameters, fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration))), - aliasSymbol, aliasTypeArguments)); + const filledTypeArguments = fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration)); + const mapper = createTypeMapper(typeParameters, filledTypeArguments); + instantiation = instantiateTypeWithAlias(type, mapper, aliasSymbol, aliasTypeArguments); + links.instantiations!.set(id, instantiation); } return instantiation; } @@ -15799,7 +15896,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function addTypeToUnion(typeSet: Type[], includes: TypeFlags, type: Type) { const flags = type.flags; if (flags & TypeFlags.Union) { - return addTypesToUnion(typeSet, includes | (isNamedUnionType(type) ? TypeFlags.Union : 0), (type as UnionType).types); + return addTypesToUnion(typeSet, includes | (isNamedUnionType(type) ? TypeFlags.Union : 0n), (type as UnionType).types); } // We ignore 'never' types in unions if (!(flags & TypeFlags.Never)) { @@ -15902,7 +15999,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const t = types[i]; const flags = t.flags; const remove = - flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) && includes & TypeFlags.String || + flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print) && includes & TypeFlags.String || flags & TypeFlags.NumberLiteral && includes & TypeFlags.Number || flags & TypeFlags.BigIntLiteral && includes & TypeFlags.BigInt || flags & TypeFlags.UniqueESSymbol && includes & TypeFlags.ESSymbol || @@ -15967,7 +16064,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return types[0]; } let typeSet: Type[] | undefined = []; - const includes = addTypesToUnion(typeSet, 0 as TypeFlags, types); + const includes = addTypesToUnion(typeSet, 0n as TypeFlags, types); if (unionReduction !== UnionReduction.None) { if (includes & TypeFlags.AnyOrUnknown) { return includes & TypeFlags.Any ? @@ -15980,7 +16077,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { orderedRemoveItemAt(typeSet, 1); } } - if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) || includes & TypeFlags.Void && includes & TypeFlags.Undefined) { + if (includes & (TypeFlags.Literal | TypeFlags.UniqueESSymbol | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print) || includes & TypeFlags.Void && includes & TypeFlags.Undefined) { removeRedundantLiteralTypes(typeSet, includes, !!(unionReduction & UnionReduction.Subtype)); } if (includes & TypeFlags.StringLiteral && includes & TypeFlags.TemplateLiteral) { @@ -16151,7 +16248,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { i--; const t = types[i]; const remove = - t.flags & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) || + t.flags & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print) || t.flags & TypeFlags.Number && includes & TypeFlags.NumberLiteral || t.flags & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral || t.flags & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol || @@ -16282,7 +16379,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // for intersections of types with signatures can be deterministic. function getIntersectionType(types: readonly Type[], aliasSymbol?: Symbol, aliasTypeArguments?: readonly Type[], noSupertypeReduction?: boolean): Type { const typeMembershipMap: Map = new Map(); - const includes = addTypesToIntersection(typeMembershipMap, 0 as TypeFlags, types); + const includes = addTypesToIntersection(typeMembershipMap, 0n as TypeFlags, types); const typeSet: Type[] = arrayFrom(typeMembershipMap.values()); // An intersection type is considered empty if it contains // the type never, or @@ -16314,7 +16411,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!strictNullChecks && includes & TypeFlags.Nullable) { return includes & TypeFlags.IncludesEmptyObject ? neverType : includes & TypeFlags.Undefined ? undefinedType : nullType; } - if (includes & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) || + if (includes & TypeFlags.String && includes & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print) || includes & TypeFlags.Number && includes & TypeFlags.NumberLiteral || includes & TypeFlags.BigInt && includes & TypeFlags.BigIntLiteral || includes & TypeFlags.ESSymbol && includes & TypeFlags.UniqueESSymbol || @@ -16584,7 +16681,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { type === wildcardType ? wildcardType : type.flags & TypeFlags.Unknown ? neverType : type.flags & (TypeFlags.Any | TypeFlags.Never) ? keyofConstraintType : - getLiteralTypeFromProperties(type, (noIndexSignatures ? TypeFlags.StringLiteral : TypeFlags.StringLike) | (stringsOnly ? 0 : TypeFlags.NumberLike | TypeFlags.ESSymbolLike), + getLiteralTypeFromProperties(type, (noIndexSignatures ? TypeFlags.StringLiteral : TypeFlags.StringLike) | (stringsOnly ? 0n : TypeFlags.NumberLike | TypeFlags.ESSymbolLike), stringsOnly === keyofStringsOnly && !noIndexSignatures); } @@ -16774,6 +16871,62 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return type; } + function createSelfType() { + const selfType = createTypeParameter() as TypeParameter & IntrinsicType; + selfType.intrinsicName = "self"; + selfType.flags |= TypeFlags.Self; + return selfType; + } + + function createSelfedType(type: Type, selfType: Type) { + const selfedType = createType(TypeFlags.Selfed) as SelfedType; + selfedType.type = type; + selfedType.selfType = selfType; + selfedType.instantiations = new Map(); + return selfedType; + } + + function createNeverWithErrorType(errorType: Type) { + const id = `${getTypeId(errorType)}`; + if (neverWithErrorTypes.has(id)) return neverWithErrorTypes.get(id)!; + + const type = createType(TypeFlags.Never | TypeFlags.NeverWithError) as NeverWithErrorType; + type.intrinsicName = "NeverWithError"; + type.errorType = errorType; + + neverWithErrorTypes.set(id, type); + return type; + } + + function createPrintType(type: Type, flagType: Type | undefined = neverType) { + const id = `${getTypeId(type)},${getTypeId(flagType)}`; + if (printTypes.has(id)) return printTypes.get(id)!; + + const printType = createType(TypeFlags.Print) as PrintType; + printType.type = type; + printType.flagType = flagType; + + printTypes.set(id, printType); + return printType; + } + + function getStringLiteralTypeFromPrintType(printType: PrintType) { + if (printType.resolvedStringLiteralType) { + return printType.resolvedStringLiteralType; + } + + const type = getStringLiteralType(typeToString( + printType.type, /* enclosingDeclaration */ undefined, + getTypeToStringDefaultFlags() | + (isTypeSubtypeOf(getStringLiteralType("InTypeAlias"), printType.flagType) + ? TypeFormatFlags.InTypeAlias + : 0) + )); + + printType.resolvedStringLiteralType = type; + return type; + } + /** * Returns if a type is or consists of a JSLiteral object type * In addition to objects which are directly literals, @@ -17027,7 +17180,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function isPatternLiteralType(type: Type) { return !!(type.flags & TypeFlags.TemplateLiteral) && every((type as TemplateLiteralType).types, isPatternLiteralPlaceholderType) || - !!(type.flags & TypeFlags.StringMapping) && isPatternLiteralPlaceholderType((type as StringMappingType).type); + !!(type.flags & TypeFlags.StringMapping) && isPatternLiteralPlaceholderType((type as StringMappingType).type) || + !!(type.flags & TypeFlags.Print); } function isGenericType(type: Type): boolean { @@ -17058,7 +17212,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return (type as SubstitutionType).objectFlags & ObjectFlags.IsGenericType; } return (type.flags & TypeFlags.InstantiableNonPrimitive || isGenericMappedType(type) || isGenericTupleType(type) ? ObjectFlags.IsGenericObjectType : 0) | - (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) && !isPatternLiteralType(type) ? ObjectFlags.IsGenericIndexType : 0); + (type.flags & (TypeFlags.InstantiableNonPrimitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print) && !isPatternLiteralType(type) ? ObjectFlags.IsGenericIndexType : 0); } function getSimplifiedType(type: Type, writing: boolean): Type { @@ -17950,6 +18104,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return links.resolvedType; } + function getTypeFromSelfTypeNode(node: Node): Type { + const links = getNodeLinks(node); + if (links.resolvedType) return links.resolvedType; + + const typeAliasDeclaration = findAncestor(node, n => n.kind === SyntaxKind.TypeAliasDeclaration); + if (!typeAliasDeclaration) return errorType; + const typeAliasLinks = getSymbolLinks(getSymbolOfNode(typeAliasDeclaration)!); + if (typeAliasLinks.selfType) { + links.resolvedType = typeAliasLinks.selfType; + return links.resolvedType; + } + + const localSelfType = createSelfType(); + typeAliasLinks.selfType = localSelfType; + + links.resolvedType = localSelfType; + return links.resolvedType; + } + function getTypeFromRestTypeNode(node: RestTypeNode | NamedTupleMember) { return getTypeFromTypeNode(getArrayElementTypeNode(node.type) || node.type); } @@ -18012,6 +18185,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return neverType; case SyntaxKind.ObjectKeyword: return node.flags & NodeFlags.JavaScriptFile && !noImplicitAny ? anyType : nonPrimitiveType; + case SyntaxKind.SelfKeyword: + return getTypeFromSelfTypeNode(node); case SyntaxKind.IntrinsicKeyword: return intrinsicMarkerType; case SyntaxKind.ThisType: @@ -18609,6 +18784,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (flags & TypeFlags.StringMapping) { return getStringMappingType((type as StringMappingType).symbol, instantiateType((type as StringMappingType).type, mapper)); } + if (flags & TypeFlags.Print) { + return createPrintType( + instantiateType((type as PrintType).type, mapper), + instantiateType((type as PrintType).flagType, mapper) + ); + } if (flags & TypeFlags.IndexedAccess) { const newAliasSymbol = aliasSymbol || type.aliasSymbol; const newAliasTypeArguments = aliasSymbol ? aliasTypeArguments : instantiateTypes(type.aliasTypeArguments, mapper); @@ -18631,9 +18812,44 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } return newBaseType.flags & TypeFlags.TypeVariable ? getSubstitutionType(newBaseType, newConstraint) : getIntersectionType([newConstraint, newBaseType]); } + if (flags & TypeFlags.Selfed) { + return createSelfedType( + instantiateType((type as SelfedType).type, mapper), + (type as SelfedType).selfType + ); + } + if (flags & TypeFlags.NeverWithError) { + return createNeverWithErrorType(instantiateType((type as NeverWithErrorType).errorType, mapper)); + } return type; } + function instantiateSelfTypesIfRequired(source: Type, target: Type): [Type, Type] { + if (!(source.flags & TypeFlags.Selfed) && !(target.flags & TypeFlags.Selfed)) { + return [source, target]; + } + if (source.flags & TypeFlags.Selfed && target.flags & TypeFlags.Selfed) { + if (getTypeId(target) === getTypeId(source)) return [source, target]; + return [(source as SelfedType).type, (target as SelfedType).type]; + } + if (source.flags & TypeFlags.Selfed) { + return [instantiateSelfType(source as SelfedType, target), target]; + } + if (target.flags & TypeFlags.Selfed) { + return [source, instantiateSelfType(target as SelfedType, source)]; + } + return Debug.fail(); + } + + function instantiateSelfType(selfed: SelfedType, self: Type) { + if (selfed.instantiations.has(getTypeId(self).toString())) { + return selfed.instantiations.get(getTypeId(self).toString())!; + } + const instantiated = instantiateType(selfed.type, makeUnaryTypeMapper(selfed.selfType, self)); + selfed.instantiations.set(getTypeId(self).toString(), instantiated); + return instantiated; + } + function instantiateReverseMappedType(type: ReverseMappedType, mapper: TypeMapper) { const innerMappedType = instantiateType(type.mappedType, mapper); if (!(getObjectFlags(innerMappedType) & ObjectFlags.Mapped)) { @@ -19582,7 +19798,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return true; } - function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter) { + function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter): boolean { + [source, target] = instantiateSelfTypesIfRequired(source, target); const s = source.flags; const t = target.flags; if (t & TypeFlags.AnyOrUnknown || s & TypeFlags.Never || source === wildcardType) return true; @@ -19626,6 +19843,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isTypeRelatedTo(source: Type, target: Type, relation: Map) { + [source, target] = instantiateSelfTypesIfRequired(source, target); if (isFreshLiteralType(source)) { source = (source as FreshableType).regularType; } @@ -19932,61 +20150,87 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let generalizedSource = source; let generalizedSourceType = sourceType; - if (isLiteralType(source) && !typeCouldHaveTopLevelSingletonTypes(target)) { - generalizedSource = getBaseTypeOfLiteralType(source); - Debug.assert(!isTypeAssignableTo(generalizedSource, target), "generalized source shouldn't be assignable"); - generalizedSourceType = getTypeNameForErrorDisplay(generalizedSource); - } + if (target.flags & TypeFlags.NeverWithError) { + const errorType = (target as NeverWithErrorType).errorType; + const errorsType = (isTypeSubtypeOf(errorType, stringType) ? createTupleType([errorType]) : errorType); + if (!isTupleType(errorsType)) return reportNonCustom(); - if (target.flags & TypeFlags.TypeParameter && target !== markerSuperTypeForCheck && target !== markerSubTypeForCheck) { - const constraint = getBaseConstraintOfType(target); - let needsOriginalSource; - if (constraint && (isTypeAssignableTo(generalizedSource, constraint) || (needsOriginalSource = isTypeAssignableTo(source, constraint)))) { - reportError( - Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2, - needsOriginalSource ? sourceType : generalizedSourceType, - targetType, - typeToString(constraint), - ); - } - else { - errorInfo = undefined; + const errorTypes: Type[] = Array.from({ length: errorsType.target.fixedLength }, (_, i) => getTupleElementType(errorsType, i)!); + if (!every(errorTypes, t => !!(t.flags & TypeFlags.StringLike))) return reportNonCustom(); + + while (errorTypes.length > 0) { reportError( - Diagnostics._0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1, - targetType, - generalizedSourceType + Diagnostics._0, + typeToString( + errorTypes.pop()!, + /* enclosingDeclaration */ undefined, + TypeFormatFlags.NoStringLiteralEscaping | getTypeToStringDefaultFlags() + ) + .slice(1,-1) ); } + return; } - - if (!message) { - if (relation === comparableRelation) { - message = Diagnostics.Type_0_is_not_comparable_to_type_1; - } - else if (sourceType === targetType) { - message = Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated; - } - else if (exactOptionalPropertyTypes && getExactOptionalUnassignableProperties(source, target).length) { - message = Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; + return reportNonCustom(); + + function reportNonCustom() { + if (isLiteralType(source) && !typeCouldHaveTopLevelSingletonTypes(target)) { + generalizedSource = getBaseTypeOfLiteralType(source); + // TODO: this is failing, so is this now a false positive or is it still valid? + // Debug.assert(!isTypeAssignableTo(generalizedSource, target), "generalized source shouldn't be assignable"); + generalizedSourceType = getTypeNameForErrorDisplay(generalizedSource); + } + + if (target.flags & TypeFlags.TypeParameter && target !== markerSuperTypeForCheck && target !== markerSubTypeForCheck) { + const constraint = getBaseConstraintOfType(target); + let needsOriginalSource; + if (constraint && (isTypeAssignableTo(generalizedSource, constraint) || (needsOriginalSource = isTypeAssignableTo(source, constraint)))) { + reportError( + Diagnostics._0_is_assignable_to_the_constraint_of_type_1_but_1_could_be_instantiated_with_a_different_subtype_of_constraint_2, + needsOriginalSource ? sourceType : generalizedSourceType, + targetType, + typeToString(constraint), + ); + } + else { + errorInfo = undefined; + reportError( + Diagnostics._0_could_be_instantiated_with_an_arbitrary_type_which_could_be_unrelated_to_1, + targetType, + generalizedSourceType + ); + } } - else { - if (source.flags & TypeFlags.StringLiteral && target.flags & TypeFlags.Union) { - const suggestedType = getSuggestedTypeForNonexistentStringLiteralType(source as StringLiteralType, target as UnionType); - if (suggestedType) { - reportError(Diagnostics.Type_0_is_not_assignable_to_type_1_Did_you_mean_2, generalizedSourceType, targetType, typeToString(suggestedType)); - return; + + if (!message) { + if (relation === comparableRelation) { + message = Diagnostics.Type_0_is_not_comparable_to_type_1; + } + else if (sourceType === targetType) { + message = Diagnostics.Type_0_is_not_assignable_to_type_1_Two_different_types_with_this_name_exist_but_they_are_unrelated; + } + else if (exactOptionalPropertyTypes && getExactOptionalUnassignableProperties(source, target).length) { + message = Diagnostics.Type_0_is_not_assignable_to_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; + } + else { + if (source.flags & TypeFlags.StringLiteral && target.flags & TypeFlags.Union) { + const suggestedType = getSuggestedTypeForNonexistentStringLiteralType(source as StringLiteralType, target as UnionType); + if (suggestedType) { + reportError(Diagnostics.Type_0_is_not_assignable_to_type_1_Did_you_mean_2, generalizedSourceType, targetType, typeToString(suggestedType)); + return; + } } + message = Diagnostics.Type_0_is_not_assignable_to_type_1; } - message = Diagnostics.Type_0_is_not_assignable_to_type_1; } - } - else if (message === Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1 - && exactOptionalPropertyTypes - && getExactOptionalUnassignableProperties(source, target).length) { - message = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; - } + else if (message === Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1 + && exactOptionalPropertyTypes + && getExactOptionalUnassignableProperties(source, target).length) { + message = Diagnostics.Argument_of_type_0_is_not_assignable_to_parameter_of_type_1_with_exactOptionalPropertyTypes_Colon_true_Consider_adding_undefined_to_the_types_of_the_target_s_properties; + } - reportError(message, generalizedSourceType, targetType); + reportError(message, generalizedSourceType, targetType); + } } function tryElaborateErrorsForPrimitivesAndObjects(source: Type, target: Type) { @@ -20047,6 +20291,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * * Ternary.False if they are not related. */ function isRelatedTo(originalSource: Type, originalTarget: Type, recursionFlags: RecursionFlags = RecursionFlags.Both, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { + [originalSource, originalTarget] = instantiateSelfTypesIfRequired(originalSource, originalTarget); // Before normalization: if `source` is type an object type, and `target` is primitive, // skip all the checks we don't need and just return `isSimpleTypeRelatedTo` result if (originalSource.flags & TypeFlags.Object && originalTarget.flags & TypeFlags.Primitive) { @@ -22535,7 +22780,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function getCombinedTypeFlags(types: Type[]): TypeFlags { - return reduceLeft(types, (flags, t) => flags | (t.flags & TypeFlags.Union ? getCombinedTypeFlags((t as UnionType).types) : t.flags), 0); + return reduceLeft(types, (flags, t) => flags | (t.flags & TypeFlags.Union ? getCombinedTypeFlags((t as UnionType).types) : t.flags), 0n); } function getCommonSupertype(types: Type[]): Type { @@ -22672,7 +22917,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getBaseTypeOfLiteralType(type: Type): Type { return type.flags & TypeFlags.EnumLiteral ? getBaseTypeOfEnumLiteralType(type as LiteralType) : - type.flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ? stringType : + type.flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print) ? stringType : type.flags & TypeFlags.NumberLiteral ? numberType : type.flags & TypeFlags.BigIntLiteral ? bigintType : type.flags & TypeFlags.BooleanLiteral ? booleanType : @@ -22803,7 +23048,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { */ function getNullableType(type: Type, flags: TypeFlags): Type { const missing = (flags & ~type.flags) & (TypeFlags.Undefined | TypeFlags.Null); - return missing === 0 ? type : + return missing === 0n ? type : missing === TypeFlags.Undefined ? getUnionType([type, undefinedType]) : missing === TypeFlags.Null ? getUnionType([type, nullType]) : getUnionType([type, undefinedType, nullType]); @@ -22879,8 +23124,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * @param target */ function isCoercibleUnderDoubleEquals(source: Type, target: Type): boolean { - return ((source.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.BooleanLiteral)) !== 0) - && ((target.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.Boolean)) !== 0); + return ((source.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.BooleanLiteral)) !== 0n) + && ((target.flags & (TypeFlags.Number | TypeFlags.String | TypeFlags.Boolean)) !== 0n); } /** @@ -23358,7 +23603,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { objectFlags & ObjectFlags.Reference && ((type as TypeReference).node || forEach(getTypeArguments(type as TypeReference), couldContainTypeVariables)) || objectFlags & ObjectFlags.Anonymous && type.symbol && type.symbol.flags & (SymbolFlags.Function | SymbolFlags.Method | SymbolFlags.Class | SymbolFlags.TypeLiteral | SymbolFlags.ObjectLiteral) && type.symbol.declarations || objectFlags & (ObjectFlags.Mapped | ObjectFlags.ReverseMapped | ObjectFlags.ObjectRestType | ObjectFlags.InstantiationExpressionType)) || - type.flags & TypeFlags.UnionOrIntersection && !(type.flags & TypeFlags.EnumLiteral) && !isNonGenericTopLevelType(type) && some((type as UnionOrIntersectionType).types, couldContainTypeVariables)); + type.flags & TypeFlags.UnionOrIntersection && !(type.flags & TypeFlags.EnumLiteral) && !isNonGenericTopLevelType(type) && some((type as UnionOrIntersectionType).types, couldContainTypeVariables) || + type.flags & TypeFlags.Selfed && couldContainTypeVariables((type as SelfedType).type) || + type.flags & TypeFlags.NeverWithError && couldContainTypeVariables((type as NeverWithErrorType).errorType)); if (type.flags & TypeFlags.ObjectFlagsType) { (type as ObjectFlagsType).objectFlags |= ObjectFlags.CouldContainTypeVariablesComputed | (result ? ObjectFlags.CouldContainTypeVariables : 0); } @@ -23366,7 +23613,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isNonGenericTopLevelType(type: Type) { - if (type.aliasSymbol && !type.aliasTypeArguments) { + if (type.aliasSymbol && !type.aliasTypeArguments && !getSymbolLinks(type.aliasSymbol).selfType) { const declaration = getDeclarationOfKind(type.aliasSymbol, SyntaxKind.TypeAliasDeclaration); return !!(declaration && findAncestor(declaration.parent, n => n.kind === SyntaxKind.SourceFile ? true : n.kind === SyntaxKind.ModuleDeclaration ? false : "quit")); } @@ -23587,7 +23834,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isValidTypeForTemplateLiteralPlaceholder(source: Type, target: Type): boolean { - if (source === target || target.flags & (TypeFlags.Any | TypeFlags.String)) { + if (source === target || target.flags & (TypeFlags.Any | TypeFlags.String | TypeFlags.Print)) { return true; } if (source.flags & TypeFlags.StringLiteral) { @@ -23875,6 +24122,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { inferFromTypes((source as StringMappingType).type, (target as StringMappingType).type); } } + else if (source.flags & TypeFlags.Print && target.flags & TypeFlags.Print) { + inferFromTypes((source as PrintType).type, (target as PrintType).type); + inferFromTypes((source as PrintType).flagType, (target as PrintType).flagType); + } else if (source.flags & TypeFlags.Substitution) { inferFromTypes((source as SubstitutionType).baseType, target); inferWithPriority(getSubstitutionIntersection(source as SubstitutionType), target, InferencePriority.SubstituteSource); // Make substitute inference at a lower priority @@ -24201,7 +24452,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const constraint = inferenceContext ? getBaseConstraintOfType(inferenceContext.typeParameter) : undefined; if (constraint && !isTypeAny(constraint)) { const constraintTypes = constraint.flags & TypeFlags.Union ? (constraint as UnionType).types : [constraint]; - let allTypeFlags: TypeFlags = reduceLeft(constraintTypes, (flags, t) => flags | t.flags, 0 as TypeFlags); + let allTypeFlags: TypeFlags = reduceLeft(constraintTypes, (flags, t) => flags | t.flags, 0n as TypeFlags); // If the constraint contains `string`, we don't need to look for a more preferred type if (!(allTypeFlags & TypeFlags.String)) { @@ -24449,7 +24700,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function hasPrimitiveConstraint(type: TypeParameter): boolean { const constraint = getConstraintOfTypeParameter(type); - return !!constraint && maybeTypeOfKind(constraint.flags & TypeFlags.Conditional ? getDefaultConstraintOfConditionalType(constraint as ConditionalType) : constraint, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping); + return !!constraint && maybeTypeOfKind(constraint.flags & TypeFlags.Conditional ? getDefaultConstraintOfConditionalType(constraint as ConditionalType) : constraint, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print); } function isObjectLiteralType(type: Type) { @@ -24991,7 +25242,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { type = getBaseConstraintOfType(type) || unknownType; } const flags = type.flags; - if (flags & (TypeFlags.String | TypeFlags.StringMapping)) { + if (flags & (TypeFlags.String | TypeFlags.StringMapping | TypeFlags.Print)) { return strictNullChecks ? TypeFacts.StringStrictFacts : TypeFacts.StringFacts; } if (flags & (TypeFlags.StringLiteral | TypeFlags.TemplateLiteral)) { @@ -25405,7 +25656,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function extractTypesOfKind(type: Type, kind: TypeFlags) { - return filterType(type, t => (t.flags & kind) !== 0); + return filterType(type, t => (t.flags & kind) !== 0n); } // Return a new type in which occurrences of the string, number and bigint primitives and placeholder template @@ -25415,10 +25666,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // types we don't actually care about. function replacePrimitivesWithLiterals(typeWithPrimitives: Type, typeWithLiterals: Type) { if (maybeTypeOfKind(typeWithPrimitives, TypeFlags.String | TypeFlags.TemplateLiteral | TypeFlags.Number | TypeFlags.BigInt) && - maybeTypeOfKind(typeWithLiterals, TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.NumberLiteral | TypeFlags.BigIntLiteral)) { + maybeTypeOfKind(typeWithLiterals, TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print | TypeFlags.NumberLiteral | TypeFlags.BigIntLiteral)) { return mapType(typeWithPrimitives, t => - t.flags & TypeFlags.String ? extractTypesOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) : - isPatternLiteralType(t) && !maybeTypeOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) ? extractTypesOfKind(typeWithLiterals, TypeFlags.StringLiteral) : + t.flags & TypeFlags.String ? extractTypesOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.StringLiteral | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print) : + isPatternLiteralType(t) && !maybeTypeOfKind(typeWithLiterals, TypeFlags.String | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print) ? extractTypesOfKind(typeWithLiterals, TypeFlags.StringLiteral) : t.flags & TypeFlags.Number ? extractTypesOfKind(typeWithLiterals, TypeFlags.Number | TypeFlags.NumberLiteral) : t.flags & TypeFlags.BigInt ? extractTypesOfKind(typeWithLiterals, TypeFlags.BigInt | TypeFlags.BigIntLiteral) : t); } @@ -27321,7 +27572,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // the entire control flow graph from the variable's declaration (i.e. when the flow container and // declaration container are the same). const assumeInitialized = isParameter || isAlias || isOuterVariable || isSpreadDestructuringAssignmentTarget || isModuleExports || isSameScopedBindingElement(node, declaration) || - type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0 || + type !== autoType && type !== autoArrayType && (!strictNullChecks || (type.flags & (TypeFlags.AnyOrUnknown | TypeFlags.Void)) !== 0n || isInTypeQuery(node) || isInAmbientOrTypeNode(node) || node.parent.kind === SyntaxKind.ExportSpecifier) || node.parent.kind === SyntaxKind.NonNullExpression || declaration.kind === SyntaxKind.VariableDeclaration && (declaration as VariableDeclaration).exclamationToken || @@ -31720,7 +31971,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else { const contextualType = getIndexedAccessType(restType, getNumberLiteralType(i - index), AccessFlags.Contextual); const argType = checkExpressionWithContextualType(arg, contextualType, context, checkMode); - const hasPrimitiveContextualType = inConstContext || maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping); + const hasPrimitiveContextualType = inConstContext || maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print); types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType)); flags.push(ElementFlags.Required); } @@ -34054,7 +34305,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getNonArrayRestType(signature: Signature) { const restType = getEffectiveRestType(signature); - return restType && !isArrayType(restType) && !isTypeAny(restType) && (getReducedType(restType).flags & TypeFlags.Never) === 0 ? restType : undefined; + return restType && !isArrayType(restType) && !isTypeAny(restType) && (getReducedType(restType).flags & TypeFlags.Never) === 0n ? restType : undefined; } function getTypeOfFirstParameterOfSignature(signature: Signature) { @@ -35345,7 +35596,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isTypeEqualityComparableTo(source: Type, target: Type) { - return (target.flags & TypeFlags.Nullable) !== 0 || isTypeComparableTo(source, target); + return (target.flags & TypeFlags.Nullable) !== 0n || isTypeComparableTo(source, target); } function createCheckBinaryExpression() { @@ -36176,7 +36427,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } // If the contextual type is a literal of a particular primitive type, we consider this a // literal context for all literals of that primitive type. - return !!(contextualType.flags & (TypeFlags.StringLiteral | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) || + return !!(contextualType.flags & (TypeFlags.StringLiteral | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print) && maybeTypeOfKind(candidateType, TypeFlags.StringLiteral) || contextualType.flags & TypeFlags.NumberLiteral && maybeTypeOfKind(candidateType, TypeFlags.NumberLiteral) || contextualType.flags & TypeFlags.BigIntLiteral && maybeTypeOfKind(candidateType, TypeFlags.BigIntLiteral) || contextualType.flags & TypeFlags.BooleanLiteral && maybeTypeOfKind(candidateType, TypeFlags.BooleanLiteral) || @@ -41157,6 +41408,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case "symbol": case "void": case "object": + case "self": error(name, message, name.escapedText as string); } } @@ -42071,7 +42323,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { checkExportsOnMergedDeclarations(node); checkTypeParameters(node.typeParameters); if (node.type.kind === SyntaxKind.IntrinsicKeyword) { - if (!intrinsicTypeKinds.has(node.name.escapedText as string) || length(node.typeParameters) !== 1) { + if (!intrinsicTypeKinds.has(node.name.escapedText as string)) { error(node.type, Diagnostics.The_intrinsic_keyword_can_only_be_used_to_declare_compiler_provided_intrinsic_types); } } diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index ffbef3ef157c4..c572403b76692 100644 --- a/src/compiler/debug.ts +++ b/src/compiler/debug.ts @@ -460,6 +460,7 @@ export namespace Debug { } export function formatTypeFlags(flags: TypeFlags | undefined): string { + // @ts-ignore TODO return formatEnum(flags, (ts as any).TypeFlags, /*isFlags*/ true); } diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7573cbc29eaf3..6f5d2b2efdba9 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -7612,5 +7612,9 @@ "The value '{0}' cannot be used here.": { "category": "Error", "code": 18050 + }, + "{0}": { + "category": "Error", + "code": 18051 } } diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 9194f03407ee3..54c6ad210660a 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -5460,7 +5460,8 @@ export function createPrinter(printerOptions: PrinterOptions = {}, handlers: Pri const textSourceNode = (node as StringLiteral).textSourceNode!; if (isIdentifier(textSourceNode) || isPrivateIdentifier(textSourceNode) || isNumericLiteral(textSourceNode)) { const text = isNumericLiteral(textSourceNode) ? textSourceNode.text : getTextOfNode(textSourceNode); - return jsxAttributeEscape ? `"${escapeJsxAttributeString(text)}"` : + return getEmitFlags(node) & EmitFlags.NoStringEscaping ? `"${text}"` : + jsxAttributeEscape ? `"${escapeJsxAttributeString(text)}"` : neverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? `"${escapeString(text)}"` : `"${escapeNonAsciiString(text)}"`; } diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 99811f7a315f1..75a971765f51c 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1348,6 +1348,7 @@ export function createNodeFactory(flags: NodeFactoryFlags, baseFactory: BaseNode case SyntaxKind.SymbolKeyword: case SyntaxKind.VoidKeyword: case SyntaxKind.UnknownKeyword: + case SyntaxKind.SelfKeyword: case SyntaxKind.UndefinedKeyword: // `undefined` is an Identifier in the expression case. transformFlags = TransformFlags.ContainsTypeScript; break; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index d2f481e50ddba..63979bba1507b 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4467,6 +4467,7 @@ namespace Parser { case SyntaxKind.UndefinedKeyword: case SyntaxKind.NeverKeyword: case SyntaxKind.ObjectKeyword: + case SyntaxKind.SelfKeyword: // If these are followed by a dot, then parse these out as a dotted type reference instead. return tryParse(parseKeywordAndNoDot) || parseTypeReference(); case SyntaxKind.AsteriskEqualsToken: @@ -4542,6 +4543,7 @@ namespace Parser { case SyntaxKind.ThisKeyword: case SyntaxKind.TypeOfKeyword: case SyntaxKind.NeverKeyword: + case SyntaxKind.SelfKeyword: case SyntaxKind.OpenBraceToken: case SyntaxKind.OpenBracketToken: case SyntaxKind.LessThanToken: diff --git a/src/compiler/scanner.ts b/src/compiler/scanner.ts index bdb2fe6ef239e..a82da28863ada 100644 --- a/src/compiler/scanner.ts +++ b/src/compiler/scanner.ts @@ -168,6 +168,7 @@ export const textToKeywordObj: MapLike = { return: SyntaxKind.ReturnKeyword, satisfies: SyntaxKind.SatisfiesKeyword, set: SyntaxKind.SetKeyword, + self: SyntaxKind.SelfKeyword, static: SyntaxKind.StaticKeyword, string: SyntaxKind.StringKeyword, super: SyntaxKind.SuperKeyword, diff --git a/src/compiler/tracing.ts b/src/compiler/tracing.ts index 4f091195827a8..6fa1f42413af5 100644 --- a/src/compiler/tracing.ts +++ b/src/compiler/tracing.ts @@ -236,7 +236,7 @@ export namespace tracingEnabled { // It's slow to compute the display text, so skip it unless it's really valuable (or cheap) let display: string | undefined; - if ((objectFlags & ObjectFlags.Anonymous) | (type.flags & TypeFlags.Literal)) { + if ((objectFlags & ObjectFlags.Anonymous) || (type.flags & TypeFlags.Literal)) { try { display = type.checker?.typeToString(type); } diff --git a/src/compiler/transformers/ts.ts b/src/compiler/transformers/ts.ts index 1b27a345ce67b..94630a5427a5e 100644 --- a/src/compiler/transformers/ts.ts +++ b/src/compiler/transformers/ts.ts @@ -619,6 +619,7 @@ export function transformTypeScript(context: TransformationContext) { case SyntaxKind.NeverKeyword: case SyntaxKind.VoidKeyword: case SyntaxKind.SymbolKeyword: + case SyntaxKind.SelfKeyword: case SyntaxKind.ConstructorType: case SyntaxKind.FunctionType: case SyntaxKind.TypeQuery: diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 44a716a516f7a..8f52ebea8aa0b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -204,6 +204,7 @@ export const enum SyntaxKind { ObjectKeyword, SatisfiesKeyword, SetKeyword, + SelfKeyword, StringKeyword, SymbolKeyword, TypeKeyword, @@ -635,6 +636,7 @@ export type KeywordSyntaxKind = | SyntaxKind.ReturnKeyword | SyntaxKind.SatisfiesKeyword | SyntaxKind.SetKeyword + | SyntaxKind.SelfKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword @@ -686,6 +688,7 @@ export type KeywordTypeSyntaxKind = | SyntaxKind.SymbolKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UnknownKeyword + | SyntaxKind.SelfKeyword | SyntaxKind.VoidKeyword ; @@ -5290,6 +5293,7 @@ export const enum NodeBuilderFlags { UseSingleQuotesForStringLiteralType = 1 << 28, // Use single quotes for string literal type NoTypeReduction = 1 << 29, // Don't call getReducedType OmitThisParameter = 1 << 25, + NoStringLiteralEscaping = 1 << 31, // Error handling AllowThisInObjectLiteral = 1 << 15, @@ -5351,12 +5355,14 @@ export const enum TypeFormatFlags { InFirstTypeArgument = 1 << 22, // Writing first type argument of the instantiated type InTypeAlias = 1 << 23, // Writing type in type alias declaration + NoStringLiteralEscaping = 1 << 31, + /** @deprecated */ WriteOwnNameForAnyLike = 0, // Does nothing NodeBuilderFlagsMask = NoTruncation | WriteArrayAsGenericType | UseStructuralFallback | WriteTypeArgumentsOfSignature | UseFullyQualifiedType | SuppressAnyReturnType | MultilineObjectLiterals | WriteClassExpressionAsTypeLiteral | UseTypeOfFunction | OmitParameterModifiers | UseAliasDefinedOutsideCurrentScope | AllowUniqueESSymbolType | InTypeAlias | - UseSingleQuotesForStringLiteralType | NoTypeReduction | OmitThisParameter + UseSingleQuotesForStringLiteralType | NoTypeReduction | OmitThisParameter | NoStringLiteralEscaping } export const enum SymbolFormatFlags { @@ -5770,6 +5776,7 @@ export interface SymbolLinks { uniqueESSymbolType?: Type; // UniqueESSymbol type for a symbol declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic) + selfType?: Type // Self type parameter of type alias (undefined if not used in declaration) outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) aliasSymbol?: Symbol; // Alias associated with generic type alias instantiation @@ -5994,97 +6001,102 @@ export interface SerializedTypeEntry { addedLength: number; } -export const enum TypeFlags { - Any = 1 << 0, - Unknown = 1 << 1, - String = 1 << 2, - Number = 1 << 3, - Boolean = 1 << 4, - Enum = 1 << 5, // Numeric computed enum member value - BigInt = 1 << 6, - StringLiteral = 1 << 7, - NumberLiteral = 1 << 8, - BooleanLiteral = 1 << 9, - EnumLiteral = 1 << 10, // Always combined with StringLiteral, NumberLiteral, or Union - BigIntLiteral = 1 << 11, - ESSymbol = 1 << 12, // Type of symbol primitive introduced in ES6 - UniqueESSymbol = 1 << 13, // unique symbol - Void = 1 << 14, - Undefined = 1 << 15, - Null = 1 << 16, - Never = 1 << 17, // Never type - TypeParameter = 1 << 18, // Type parameter - Object = 1 << 19, // Object type - Union = 1 << 20, // Union (T | U) - Intersection = 1 << 21, // Intersection (T & U) - Index = 1 << 22, // keyof T - IndexedAccess = 1 << 23, // T[K] - Conditional = 1 << 24, // T extends U ? X : Y - Substitution = 1 << 25, // Type parameter substitution - NonPrimitive = 1 << 26, // intrinsic object type - TemplateLiteral = 1 << 27, // Template literal type - StringMapping = 1 << 28, // Uppercase/Lowercase type - - /** @internal */ - AnyOrUnknown = Any | Unknown, - /** @internal */ - Nullable = Undefined | Null, - Literal = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral, - Unit = Literal | UniqueESSymbol | Nullable, - StringOrNumberLiteral = StringLiteral | NumberLiteral, - /** @internal */ - StringOrNumberLiteralOrUnique = StringLiteral | NumberLiteral | UniqueESSymbol, - /** @internal */ - DefinitelyFalsy = StringLiteral | NumberLiteral | BigIntLiteral | BooleanLiteral | Void | Undefined | Null, - PossiblyFalsy = DefinitelyFalsy | String | Number | BigInt | Boolean, - /** @internal */ - Intrinsic = Any | Unknown | String | Number | BigInt | Boolean | BooleanLiteral | ESSymbol | Void | Undefined | Null | Never | NonPrimitive, - /** @internal */ - Primitive = String | Number | BigInt | Boolean | Enum | EnumLiteral | ESSymbol | Void | Undefined | Null | Literal | UniqueESSymbol, - StringLike = String | StringLiteral | TemplateLiteral | StringMapping, - NumberLike = Number | NumberLiteral | Enum, - BigIntLike = BigInt | BigIntLiteral, - BooleanLike = Boolean | BooleanLiteral, - EnumLike = Enum | EnumLiteral, - ESSymbolLike = ESSymbol | UniqueESSymbol, - VoidLike = Void | Undefined, - /** @internal */ - DefinitelyNonNullable = StringLike | NumberLike | BigIntLike | BooleanLike | EnumLike | ESSymbolLike | Object | NonPrimitive, - /** @internal */ - DisjointDomains = NonPrimitive | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbolLike | VoidLike | Null, - UnionOrIntersection = Union | Intersection, - StructuredType = Object | Union | Intersection, - TypeVariable = TypeParameter | IndexedAccess, - InstantiableNonPrimitive = TypeVariable | Conditional | Substitution, - InstantiablePrimitive = Index | TemplateLiteral | StringMapping, - Instantiable = InstantiableNonPrimitive | InstantiablePrimitive, - StructuredOrInstantiable = StructuredType | Instantiable, - /** @internal */ - ObjectFlagsType = Any | Nullable | Never | Object | Union | Intersection, - /** @internal */ - Simplifiable = IndexedAccess | Conditional, - /** @internal */ - Singleton = Any | Unknown | String | Number | Boolean | BigInt | ESSymbol | Void | Undefined | Null | Never | NonPrimitive, +export type TypeFlags = (typeof TypeFlags)[keyof typeof TypeFlags]; +export const TypeFlags = new class TypeFlags { + Any = 1n << 0n; + Unknown = 1n << 1n; + String = 1n << 2n; + Number = 1n << 3n; + Boolean = 1n << 4n; + Enum = 1n << 5n; // Numeric computed enum member value + BigInt = 1n << 6n; + StringLiteral = 1n << 7n; + NumberLiteral = 1n << 8n; + BooleanLiteral = 1n << 9n; + EnumLiteral = 1n << 10n; // Always combined with StringLiteral, NumberLiteral, or Union + BigIntLiteral = 1n << 11n; + ESSymbol = 1n << 12n; // Type of symbol primitive introduced in ES6 + UniqueESSymbol = 1n << 13n; // unique symbol + Void = 1n << 14n; + Undefined = 1n << 15n; + Null = 1n << 16n; + Never = 1n << 17n; // Never type + TypeParameter = 1n << 18n; // Type parameter + Object = 1n << 19n; // Object type + Union = 1n << 20n; // Union (T | U) + Intersection = 1n << 21n; // Intersection (T & U) + Index = 1n << 22n; // keyof T + IndexedAccess = 1n << 23n; // T[K] + Conditional = 1n << 24n; // T extends U ? X : Y + Substitution = 1n << 25n; // Type parameter substitution + NonPrimitive = 1n << 26n; // intrinsic object type + TemplateLiteral = 1n << 27n; // Template literal type + StringMapping = 1n << 28n; // Uppercase/Lowercase type + Self = 1n << 29n; + Selfed = 1n << 30n; + NeverWithError = 1n << 31n; + Print = 1n << 32n; + + /** @internal */ + AnyOrUnknown = this.Any | this.Unknown; + /** @internal */ + Nullable = this.Undefined | this.Null; + Literal = this.StringLiteral | this.NumberLiteral | this.BigIntLiteral | this.BooleanLiteral; + Unit = this.Literal | this.UniqueESSymbol | this.Nullable; + StringOrNumberLiteral = this.StringLiteral | this.NumberLiteral; + /** @internal */ + StringOrNumberLiteralOrUnique = this.StringLiteral | this.NumberLiteral | this.UniqueESSymbol; + /** @internal */ + DefinitelyFalsy = this.StringLiteral | this.NumberLiteral | this.BigIntLiteral | this.BooleanLiteral | this.Void | this.Undefined | this.Null; + PossiblyFalsy = this.DefinitelyFalsy | this.String | this.Number | this.BigInt | this.Boolean; + /** @internal */ + Intrinsic = this.Any | this.Unknown | this.String | this.Number | this.BigInt | this.Boolean | this.BooleanLiteral | this.ESSymbol | this.Void | this.Undefined | this.Null | this.Never | this.NonPrimitive; + /** @internal */ + Primitive = this.String | this.Number | this.BigInt | this.Boolean | this.Enum | this.EnumLiteral | this.ESSymbol | this.Void | this.Undefined | this.Null | this.Literal | this.UniqueESSymbol; + StringLike = this.String | this.StringLiteral | this.TemplateLiteral | this.StringMapping | this.Print; + NumberLike = this.Number | this.NumberLiteral | this.Enum; + BigIntLike = this.BigInt | this.BigIntLiteral; + BooleanLike = this.Boolean | this.BooleanLiteral; + EnumLike = this.Enum | this.EnumLiteral; + ESSymbolLike = this.ESSymbol | this.UniqueESSymbol; + VoidLike = this.Void | this.Undefined; + /** @internal */ + DefinitelyNonNullable = this.StringLike | this.NumberLike | this.BigIntLike | this.BooleanLike | this.EnumLike | this.ESSymbolLike | this.Object | this.NonPrimitive; + /** @internal */ + DisjointDomains = this.NonPrimitive | this.StringLike | this.NumberLike | this.BigIntLike | this.BooleanLike | this.ESSymbolLike | this.VoidLike | this.Null; + UnionOrIntersection = this.Union | this.Intersection; + StructuredType = this.Object | this.Union | this.Intersection; + TypeVariable = this.TypeParameter | this.IndexedAccess; + InstantiableNonPrimitive = this.TypeVariable | this.Conditional | this.Substitution | this.Selfed | this.NeverWithError; + InstantiablePrimitive = this.Index | this.TemplateLiteral | this.StringMapping | this.Print; + Instantiable = this.InstantiableNonPrimitive | this.InstantiablePrimitive; + StructuredOrInstantiable = this.StructuredType | this.Instantiable; + /** @internal */ + ObjectFlagsType = this.Any | this.Nullable | this.Never | this.Object | this.Union | this.Intersection; + /** @internal */ + Simplifiable = this.IndexedAccess | this.Conditional; + /** @internal */ + Singleton = this.Any | this.Unknown | this.String | this.Number | this.Boolean | this.BigInt | this.ESSymbol | this.Void | this.Undefined | this.Null | this.Never | this.NonPrimitive; // 'Narrowable' types are types where narrowing actually narrows. // This *should* be every type other than null, undefined, void, and never - Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive, + Narrowable = this.Any | this.Unknown | this.StructuredOrInstantiable | this.StringLike | this.NumberLike | this.BigIntLike | this.BooleanLike | this.ESSymbol | this.UniqueESSymbol | this.NonPrimitive; // The following flags are aggregated during union and intersection type construction /** @internal */ - IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive | TemplateLiteral, + IncludesMask = this.Any | this.Unknown | this.Primitive | this.Never | this.Object | this.Union | this.Intersection | this.NonPrimitive | this.TemplateLiteral; // The following flags are used for different purposes during union and intersection type construction /** @internal */ - IncludesMissingType = TypeParameter, + IncludesMissingType = this.TypeParameter; /** @internal */ - IncludesNonWideningType = Index, + IncludesNonWideningType = this.Index; /** @internal */ - IncludesWildcard = IndexedAccess, + IncludesWildcard = this.IndexedAccess; /** @internal */ - IncludesEmptyObject = Conditional, + IncludesEmptyObject = this.Conditional; /** @internal */ - IncludesInstantiable = Substitution, + IncludesInstantiable = this.Substitution; /** @internal */ - NotPrimitiveUnion = Any | Unknown | Enum | Void | Never | Object | Intersection | IncludesInstantiable, -} + NotPrimitiveUnion = this.Any | this.Unknown | this.Enum | this.Void | this.Never | this.Object | this.Intersection | this.IncludesInstantiable; +}(); export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; @@ -6591,7 +6603,6 @@ export interface StringMappingType extends InstantiableType { symbol: Symbol; type: Type; } - // Type parameter substitution (TypeFlags.Substitution) // Substitution types are created for type parameters or indexed access types that occur in the // true branch of a conditional type. For example, in 'T extends string ? Foo : Bar', the @@ -6604,6 +6615,24 @@ export interface SubstitutionType extends InstantiableType { constraint: Type; // Constraint that target type is known to satisfy } +export interface SelfedType extends InstantiableType { + type: Type + selfType: Type + instantiations: Map +} + +/** @internal */ +export interface NeverWithErrorType extends InstantiableType, IntrinsicType { + errorType: Type +} + +export interface PrintType extends InstantiableType { + type: Type + flagType: Type + resolvedStringLiteralType: StringLiteralType +} + + /** @internal */ export const enum JsxReferenceKind { Component, @@ -7890,6 +7919,7 @@ export const enum EmitFlags { /** @internal */ IgnoreSourceNewlines = 1 << 28, // Overrides `printerOptions.preserveSourceNewlines` to print this node (and all descendants) with default whitespace. /** @internal */ Immutable = 1 << 29, // Indicates a node is a singleton intended to be reused in multiple locations. Any attempt to make further changes to the node will result in an error. /** @internal */ IndirectCall = 1 << 30, // Emit CallExpression as an indirect call: `(0, f)()` + NoStringEscaping = 1 << 31 } export interface EmitHelperBase { diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 56b18ff90056d..70a75dddc97d8 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1281,7 +1281,8 @@ export function getLiteralText(node: LiteralLikeNode, sourceFile: SourceFile | u // or a (possibly escaped) quoted form of the original text if it's string-like. switch (node.kind) { case SyntaxKind.StringLiteral: { - const escapeText = flags & GetLiteralTextFlags.JsxAttributeEscape ? escapeJsxAttributeString : + const escapeText = getEmitFlags(node) & EmitFlags.NoStringEscaping ? ((x: string) => x) : + flags & GetLiteralTextFlags.JsxAttributeEscape ? escapeJsxAttributeString : flags & GetLiteralTextFlags.NeverAsciiEscape || (getEmitFlags(node) & EmitFlags.NoAsciiEscaping) ? escapeString : escapeNonAsciiString; if ((node as StringLiteral).singleQuote) { @@ -1995,6 +1996,7 @@ export function isPartOfTypeNode(node: Node): boolean { case SyntaxKind.ObjectKeyword: case SyntaxKind.UndefinedKeyword: case SyntaxKind.NeverKeyword: + case SyntaxKind.SelfKeyword: return true; case SyntaxKind.VoidKeyword: return node.parent.kind !== SyntaxKind.VoidExpression; @@ -7122,6 +7124,7 @@ export function isTypeNodeKind(kind: SyntaxKind): kind is TypeNodeSyntaxKind { || kind === SyntaxKind.VoidKeyword || kind === SyntaxKind.UndefinedKeyword || kind === SyntaxKind.NeverKeyword + || kind === SyntaxKind.SelfKeyword || kind === SyntaxKind.ExpressionWithTypeArguments || kind === SyntaxKind.JSDocAllType || kind === SyntaxKind.JSDocUnknownType diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index e403a4555acae..f8190fcf35e6a 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1085,13 +1085,14 @@ export namespace Completion { "number", "object", "readonly", + "self", "string", "symbol", "true", "undefined", "unique", "unknown", - "void", + "void" ].map(keywordEntry); export function sorted(entries: readonly ExpectedCompletionEntry[]): readonly ExpectedCompletionEntry[] { @@ -1192,6 +1193,8 @@ export namespace Completion { typeEntry("Lowercase"), typeEntry("Capitalize"), typeEntry("Uncapitalize"), + typeEntry("Never"), + typeEntry("Print"), interfaceEntry("ThisType"), varEntry("ArrayBuffer"), interfaceEntry("ArrayBufferTypes"), @@ -1218,7 +1221,7 @@ export namespace Completion { interfaceEntry("Float32ArrayConstructor"), varEntry("Float64Array"), interfaceEntry("Float64ArrayConstructor"), - moduleEntry("Intl"), + moduleEntry("Intl") ]; export const globalThisEntry: ExpectedCompletionEntry = { @@ -1260,6 +1263,7 @@ export namespace Completion { case "readonly": case "number": case "object": + case "self": case "string": case "symbol": case "type": @@ -1396,6 +1400,7 @@ export namespace Completion { "readonly", "return", "satisfies", + "self", "string", "super", "switch", @@ -1611,6 +1616,7 @@ export namespace Completion { "readonly", "return", "satisfies", + "self", "string", "super", "switch", diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index e3526d0e6b0bb..98f368153c70c 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1638,6 +1638,17 @@ type Capitalize = intrinsic; */ type Uncapitalize = intrinsic; +/** + * Create a never type with a custom assignability error message via a string type, + * or via a tuple of string types to create a stack of error messages + */ +type Never = intrinsic; + +/** + * Print a type to a string literal type. + */ +type Print = intrinsic; + /** * Marker for contextual 'this' type */ diff --git a/src/services/completions.ts b/src/services/completions.ts index cec01139bef9d..58b30aa21c76c 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -4679,6 +4679,7 @@ function isTypeScriptOnlyKeyword(kind: SyntaxKind) { case SyntaxKind.ProtectedKeyword: case SyntaxKind.PublicKeyword: case SyntaxKind.ReadonlyKeyword: + case SyntaxKind.SelfKeyword: case SyntaxKind.StringKeyword: case SyntaxKind.SymbolKeyword: case SyntaxKind.TypeKeyword: diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 0eca9e34446c3..221207b944e96 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -2299,6 +2299,7 @@ export const typeKeywords: readonly SyntaxKind[] = [ SyntaxKind.UndefinedKeyword, SyntaxKind.UniqueKeyword, SyntaxKind.UnknownKeyword, + SyntaxKind.SelfKeyword, ]; /** @internal */ diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index d0efb21a159c0..d00d930d1199d 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -4,8 +4,8 @@ "outDir": "../built/local", "pretty": true, - "lib": ["es2018"], - "target": "es2018", + "lib": ["es2020"], + "target": "es2020", "module": "CommonJS", "moduleResolution": "node", diff --git a/tests/baselines/reference/TwoInternalModulesThatMergeEachWithExportedLocalVarsOfTheSameName.errors.txt b/tests/baselines/reference/TwoInternalModulesThatMergeEachWithExportedLocalVarsOfTheSameName.errors.txt index fd048a987a485..4868496b06587 100644 --- a/tests/baselines/reference/TwoInternalModulesThatMergeEachWithExportedLocalVarsOfTheSameName.errors.txt +++ b/tests/baselines/reference/TwoInternalModulesThatMergeEachWithExportedLocalVarsOfTheSameName.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/internalModules/DeclarationMerging/part2.ts(3,24): error TS2304: Cannot find name 'Point'. -tests/cases/conformance/internalModules/DeclarationMerging/part2.ts(7,36): error TS2304: Cannot find name 'Point'. -tests/cases/conformance/internalModules/DeclarationMerging/part2.ts(7,54): error TS2304: Cannot find name 'Point'. +tests/cases/conformance/internalModules/DeclarationMerging/part2.ts(3,24): error TS2552: Cannot find name 'Point'. Did you mean 'Print'? +tests/cases/conformance/internalModules/DeclarationMerging/part2.ts(7,36): error TS2552: Cannot find name 'Point'. Did you mean 'Print'? +tests/cases/conformance/internalModules/DeclarationMerging/part2.ts(7,54): error TS2552: Cannot find name 'Point'. Did you mean 'Print'? ==== tests/cases/conformance/internalModules/DeclarationMerging/part1.ts (0 errors) ==== @@ -24,15 +24,15 @@ tests/cases/conformance/internalModules/DeclarationMerging/part2.ts(7,54): error // collision with 'Origin' var in other part of merged module export var Origin: Point = { x: 0, y: 0 }; ~~~~~ -!!! error TS2304: Cannot find name 'Point'. +!!! error TS2552: Cannot find name 'Point'. Did you mean 'Print'? export module Utils { export class Plane { constructor(public tl: Point, public br: Point) { } ~~~~~ -!!! error TS2304: Cannot find name 'Point'. +!!! error TS2552: Cannot find name 'Point'. Did you mean 'Print'? ~~~~~ -!!! error TS2304: Cannot find name 'Point'. +!!! error TS2552: Cannot find name 'Point'. Did you mean 'Print'? } } } diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 6f6e0a8fb4b32..2f3a52375ea86 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -4147,217 +4147,218 @@ declare namespace ts { ObjectKeyword = 149, SatisfiesKeyword = 150, SetKeyword = 151, - StringKeyword = 152, - SymbolKeyword = 153, - TypeKeyword = 154, - UndefinedKeyword = 155, - UniqueKeyword = 156, - UnknownKeyword = 157, - FromKeyword = 158, - GlobalKeyword = 159, - BigIntKeyword = 160, - OverrideKeyword = 161, - OfKeyword = 162, - QualifiedName = 163, - ComputedPropertyName = 164, - TypeParameter = 165, - Parameter = 166, - Decorator = 167, - PropertySignature = 168, - PropertyDeclaration = 169, - MethodSignature = 170, - MethodDeclaration = 171, - ClassStaticBlockDeclaration = 172, - Constructor = 173, - GetAccessor = 174, - SetAccessor = 175, - CallSignature = 176, - ConstructSignature = 177, - IndexSignature = 178, - TypePredicate = 179, - TypeReference = 180, - FunctionType = 181, - ConstructorType = 182, - TypeQuery = 183, - TypeLiteral = 184, - ArrayType = 185, - TupleType = 186, - OptionalType = 187, - RestType = 188, - UnionType = 189, - IntersectionType = 190, - ConditionalType = 191, - InferType = 192, - ParenthesizedType = 193, - ThisType = 194, - TypeOperator = 195, - IndexedAccessType = 196, - MappedType = 197, - LiteralType = 198, - NamedTupleMember = 199, - TemplateLiteralType = 200, - TemplateLiteralTypeSpan = 201, - ImportType = 202, - ObjectBindingPattern = 203, - ArrayBindingPattern = 204, - BindingElement = 205, - ArrayLiteralExpression = 206, - ObjectLiteralExpression = 207, - PropertyAccessExpression = 208, - ElementAccessExpression = 209, - CallExpression = 210, - NewExpression = 211, - TaggedTemplateExpression = 212, - TypeAssertionExpression = 213, - ParenthesizedExpression = 214, - FunctionExpression = 215, - ArrowFunction = 216, - DeleteExpression = 217, - TypeOfExpression = 218, - VoidExpression = 219, - AwaitExpression = 220, - PrefixUnaryExpression = 221, - PostfixUnaryExpression = 222, - BinaryExpression = 223, - ConditionalExpression = 224, - TemplateExpression = 225, - YieldExpression = 226, - SpreadElement = 227, - ClassExpression = 228, - OmittedExpression = 229, - ExpressionWithTypeArguments = 230, - AsExpression = 231, - NonNullExpression = 232, - MetaProperty = 233, - SyntheticExpression = 234, - SatisfiesExpression = 235, - TemplateSpan = 236, - SemicolonClassElement = 237, - Block = 238, - EmptyStatement = 239, - VariableStatement = 240, - ExpressionStatement = 241, - IfStatement = 242, - DoStatement = 243, - WhileStatement = 244, - ForStatement = 245, - ForInStatement = 246, - ForOfStatement = 247, - ContinueStatement = 248, - BreakStatement = 249, - ReturnStatement = 250, - WithStatement = 251, - SwitchStatement = 252, - LabeledStatement = 253, - ThrowStatement = 254, - TryStatement = 255, - DebuggerStatement = 256, - VariableDeclaration = 257, - VariableDeclarationList = 258, - FunctionDeclaration = 259, - ClassDeclaration = 260, - InterfaceDeclaration = 261, - TypeAliasDeclaration = 262, - EnumDeclaration = 263, - ModuleDeclaration = 264, - ModuleBlock = 265, - CaseBlock = 266, - NamespaceExportDeclaration = 267, - ImportEqualsDeclaration = 268, - ImportDeclaration = 269, - ImportClause = 270, - NamespaceImport = 271, - NamedImports = 272, - ImportSpecifier = 273, - ExportAssignment = 274, - ExportDeclaration = 275, - NamedExports = 276, - NamespaceExport = 277, - ExportSpecifier = 278, - MissingDeclaration = 279, - ExternalModuleReference = 280, - JsxElement = 281, - JsxSelfClosingElement = 282, - JsxOpeningElement = 283, - JsxClosingElement = 284, - JsxFragment = 285, - JsxOpeningFragment = 286, - JsxClosingFragment = 287, - JsxAttribute = 288, - JsxAttributes = 289, - JsxSpreadAttribute = 290, - JsxExpression = 291, - CaseClause = 292, - DefaultClause = 293, - HeritageClause = 294, - CatchClause = 295, - AssertClause = 296, - AssertEntry = 297, - ImportTypeAssertionContainer = 298, - PropertyAssignment = 299, - ShorthandPropertyAssignment = 300, - SpreadAssignment = 301, - EnumMember = 302, - UnparsedPrologue = 303, - UnparsedPrepend = 304, - UnparsedText = 305, - UnparsedInternalText = 306, - UnparsedSyntheticReference = 307, - SourceFile = 308, - Bundle = 309, - UnparsedSource = 310, - InputFiles = 311, - JSDocTypeExpression = 312, - JSDocNameReference = 313, - JSDocMemberName = 314, - JSDocAllType = 315, - JSDocUnknownType = 316, - JSDocNullableType = 317, - JSDocNonNullableType = 318, - JSDocOptionalType = 319, - JSDocFunctionType = 320, - JSDocVariadicType = 321, - JSDocNamepathType = 322, - JSDoc = 323, + SelfKeyword = 152, + StringKeyword = 153, + SymbolKeyword = 154, + TypeKeyword = 155, + UndefinedKeyword = 156, + UniqueKeyword = 157, + UnknownKeyword = 158, + FromKeyword = 159, + GlobalKeyword = 160, + BigIntKeyword = 161, + OverrideKeyword = 162, + OfKeyword = 163, + QualifiedName = 164, + ComputedPropertyName = 165, + TypeParameter = 166, + Parameter = 167, + Decorator = 168, + PropertySignature = 169, + PropertyDeclaration = 170, + MethodSignature = 171, + MethodDeclaration = 172, + ClassStaticBlockDeclaration = 173, + Constructor = 174, + GetAccessor = 175, + SetAccessor = 176, + CallSignature = 177, + ConstructSignature = 178, + IndexSignature = 179, + TypePredicate = 180, + TypeReference = 181, + FunctionType = 182, + ConstructorType = 183, + TypeQuery = 184, + TypeLiteral = 185, + ArrayType = 186, + TupleType = 187, + OptionalType = 188, + RestType = 189, + UnionType = 190, + IntersectionType = 191, + ConditionalType = 192, + InferType = 193, + ParenthesizedType = 194, + ThisType = 195, + TypeOperator = 196, + IndexedAccessType = 197, + MappedType = 198, + LiteralType = 199, + NamedTupleMember = 200, + TemplateLiteralType = 201, + TemplateLiteralTypeSpan = 202, + ImportType = 203, + ObjectBindingPattern = 204, + ArrayBindingPattern = 205, + BindingElement = 206, + ArrayLiteralExpression = 207, + ObjectLiteralExpression = 208, + PropertyAccessExpression = 209, + ElementAccessExpression = 210, + CallExpression = 211, + NewExpression = 212, + TaggedTemplateExpression = 213, + TypeAssertionExpression = 214, + ParenthesizedExpression = 215, + FunctionExpression = 216, + ArrowFunction = 217, + DeleteExpression = 218, + TypeOfExpression = 219, + VoidExpression = 220, + AwaitExpression = 221, + PrefixUnaryExpression = 222, + PostfixUnaryExpression = 223, + BinaryExpression = 224, + ConditionalExpression = 225, + TemplateExpression = 226, + YieldExpression = 227, + SpreadElement = 228, + ClassExpression = 229, + OmittedExpression = 230, + ExpressionWithTypeArguments = 231, + AsExpression = 232, + NonNullExpression = 233, + MetaProperty = 234, + SyntheticExpression = 235, + SatisfiesExpression = 236, + TemplateSpan = 237, + SemicolonClassElement = 238, + Block = 239, + EmptyStatement = 240, + VariableStatement = 241, + ExpressionStatement = 242, + IfStatement = 243, + DoStatement = 244, + WhileStatement = 245, + ForStatement = 246, + ForInStatement = 247, + ForOfStatement = 248, + ContinueStatement = 249, + BreakStatement = 250, + ReturnStatement = 251, + WithStatement = 252, + SwitchStatement = 253, + LabeledStatement = 254, + ThrowStatement = 255, + TryStatement = 256, + DebuggerStatement = 257, + VariableDeclaration = 258, + VariableDeclarationList = 259, + FunctionDeclaration = 260, + ClassDeclaration = 261, + InterfaceDeclaration = 262, + TypeAliasDeclaration = 263, + EnumDeclaration = 264, + ModuleDeclaration = 265, + ModuleBlock = 266, + CaseBlock = 267, + NamespaceExportDeclaration = 268, + ImportEqualsDeclaration = 269, + ImportDeclaration = 270, + ImportClause = 271, + NamespaceImport = 272, + NamedImports = 273, + ImportSpecifier = 274, + ExportAssignment = 275, + ExportDeclaration = 276, + NamedExports = 277, + NamespaceExport = 278, + ExportSpecifier = 279, + MissingDeclaration = 280, + ExternalModuleReference = 281, + JsxElement = 282, + JsxSelfClosingElement = 283, + JsxOpeningElement = 284, + JsxClosingElement = 285, + JsxFragment = 286, + JsxOpeningFragment = 287, + JsxClosingFragment = 288, + JsxAttribute = 289, + JsxAttributes = 290, + JsxSpreadAttribute = 291, + JsxExpression = 292, + CaseClause = 293, + DefaultClause = 294, + HeritageClause = 295, + CatchClause = 296, + AssertClause = 297, + AssertEntry = 298, + ImportTypeAssertionContainer = 299, + PropertyAssignment = 300, + ShorthandPropertyAssignment = 301, + SpreadAssignment = 302, + EnumMember = 303, + UnparsedPrologue = 304, + UnparsedPrepend = 305, + UnparsedText = 306, + UnparsedInternalText = 307, + UnparsedSyntheticReference = 308, + SourceFile = 309, + Bundle = 310, + UnparsedSource = 311, + InputFiles = 312, + JSDocTypeExpression = 313, + JSDocNameReference = 314, + JSDocMemberName = 315, + JSDocAllType = 316, + JSDocUnknownType = 317, + JSDocNullableType = 318, + JSDocNonNullableType = 319, + JSDocOptionalType = 320, + JSDocFunctionType = 321, + JSDocVariadicType = 322, + JSDocNamepathType = 323, + JSDoc = 324, /** @deprecated Use SyntaxKind.JSDoc */ - JSDocComment = 323, - JSDocText = 324, - JSDocTypeLiteral = 325, - JSDocSignature = 326, - JSDocLink = 327, - JSDocLinkCode = 328, - JSDocLinkPlain = 329, - JSDocTag = 330, - JSDocAugmentsTag = 331, - JSDocImplementsTag = 332, - JSDocAuthorTag = 333, - JSDocDeprecatedTag = 334, - JSDocClassTag = 335, - JSDocPublicTag = 336, - JSDocPrivateTag = 337, - JSDocProtectedTag = 338, - JSDocReadonlyTag = 339, - JSDocOverrideTag = 340, - JSDocCallbackTag = 341, - JSDocOverloadTag = 342, - JSDocEnumTag = 343, - JSDocParameterTag = 344, - JSDocReturnTag = 345, - JSDocThisTag = 346, - JSDocTypeTag = 347, - JSDocTemplateTag = 348, - JSDocTypedefTag = 349, - JSDocSeeTag = 350, - JSDocPropertyTag = 351, - JSDocThrowsTag = 352, - SyntaxList = 353, - NotEmittedStatement = 354, - PartiallyEmittedExpression = 355, - CommaListExpression = 356, - MergeDeclarationMarker = 357, - EndOfDeclarationMarker = 358, - SyntheticReferenceExpression = 359, - Count = 360, + JSDocComment = 324, + JSDocText = 325, + JSDocTypeLiteral = 326, + JSDocSignature = 327, + JSDocLink = 328, + JSDocLinkCode = 329, + JSDocLinkPlain = 330, + JSDocTag = 331, + JSDocAugmentsTag = 332, + JSDocImplementsTag = 333, + JSDocAuthorTag = 334, + JSDocDeprecatedTag = 335, + JSDocClassTag = 336, + JSDocPublicTag = 337, + JSDocPrivateTag = 338, + JSDocProtectedTag = 339, + JSDocReadonlyTag = 340, + JSDocOverrideTag = 341, + JSDocCallbackTag = 342, + JSDocOverloadTag = 343, + JSDocEnumTag = 344, + JSDocParameterTag = 345, + JSDocReturnTag = 346, + JSDocThisTag = 347, + JSDocTypeTag = 348, + JSDocTemplateTag = 349, + JSDocTypedefTag = 350, + JSDocSeeTag = 351, + JSDocPropertyTag = 352, + JSDocThrowsTag = 353, + SyntaxList = 354, + NotEmittedStatement = 355, + PartiallyEmittedExpression = 356, + CommaListExpression = 357, + MergeDeclarationMarker = 358, + EndOfDeclarationMarker = 359, + SyntheticReferenceExpression = 360, + Count = 361, FirstAssignment = 63, LastAssignment = 78, FirstCompoundAssignment = 64, @@ -4365,15 +4366,15 @@ declare namespace ts { FirstReservedWord = 81, LastReservedWord = 116, FirstKeyword = 81, - LastKeyword = 162, + LastKeyword = 163, FirstFutureReservedWord = 117, LastFutureReservedWord = 125, - FirstTypeNode = 179, - LastTypeNode = 202, + FirstTypeNode = 180, + LastTypeNode = 203, FirstPunctuation = 18, LastPunctuation = 78, FirstToken = 0, - LastToken = 162, + LastToken = 163, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -4382,21 +4383,21 @@ declare namespace ts { LastTemplateToken = 17, FirstBinaryOperator = 29, LastBinaryOperator = 78, - FirstStatement = 240, - LastStatement = 256, - FirstNode = 163, - FirstJSDocNode = 312, - LastJSDocNode = 352, - FirstJSDocTagNode = 330, - LastJSDocTagNode = 352 + FirstStatement = 241, + LastStatement = 257, + FirstNode = 164, + FirstJSDocNode = 313, + LastJSDocNode = 353, + FirstJSDocTagNode = 331, + LastJSDocTagNode = 353 } type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia; type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral; type PseudoLiteralSyntaxKind = SyntaxKind.TemplateHead | SyntaxKind.TemplateMiddle | SyntaxKind.TemplateTail; type PunctuationSyntaxKind = SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.CloseParenToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.DotToken | SyntaxKind.DotDotDotToken | SyntaxKind.SemicolonToken | SyntaxKind.CommaToken | SyntaxKind.QuestionDotToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanSlashToken | SyntaxKind.GreaterThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.EqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.EqualsGreaterThanToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.AsteriskToken | SyntaxKind.AsteriskAsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.ExclamationToken | SyntaxKind.TildeToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.QuestionQuestionToken | SyntaxKind.QuestionToken | SyntaxKind.ColonToken | SyntaxKind.AtToken | SyntaxKind.BacktickToken | SyntaxKind.HashToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken; - type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AccessorKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AssertKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OutKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SatisfiesKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword; + type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AccessorKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AssertKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OutKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SatisfiesKeyword | SyntaxKind.SetKeyword | SyntaxKind.SelfKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword; type ModifierSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AccessorKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.ConstKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.ExportKeyword | SyntaxKind.InKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OutKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.StaticKeyword; - type KeywordTypeSyntaxKind = SyntaxKind.AnyKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VoidKeyword; + type KeywordTypeSyntaxKind = SyntaxKind.AnyKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.SelfKeyword | SyntaxKind.VoidKeyword; type TokenSyntaxKind = SyntaxKind.Unknown | SyntaxKind.EndOfFileToken | TriviaSyntaxKind | LiteralSyntaxKind | PseudoLiteralSyntaxKind | PunctuationSyntaxKind | SyntaxKind.Identifier | KeywordSyntaxKind; type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken; type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.HashToken | SyntaxKind.Unknown | KeywordSyntaxKind; @@ -6428,6 +6429,7 @@ declare namespace ts { UseSingleQuotesForStringLiteralType = 268435456, NoTypeReduction = 536870912, OmitThisParameter = 33554432, + NoStringLiteralEscaping = -2147483648, AllowThisInObjectLiteral = 32768, AllowQualifiedNameInPlaceOfIdentifier = 65536, /** @deprecated AllowQualifedNameInPlaceOfIdentifier. Use AllowQualifiedNameInPlaceOfIdentifier instead. */ @@ -6466,8 +6468,9 @@ declare namespace ts { InElementType = 2097152, InFirstTypeArgument = 4194304, InTypeAlias = 8388608, + NoStringLiteralEscaping = -2147483648, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 848330091 + NodeBuilderFlagsMask = -1299153557 } enum SymbolFormatFlags { None = 0, @@ -6631,56 +6634,97 @@ declare namespace ts { } /** SymbolTable based on ES6 Map interface. */ type SymbolTable = UnderscoreEscapedMap; - enum TypeFlags { - Any = 1, - Unknown = 2, - String = 4, - Number = 8, - Boolean = 16, - Enum = 32, - BigInt = 64, - StringLiteral = 128, - NumberLiteral = 256, - BooleanLiteral = 512, - EnumLiteral = 1024, - BigIntLiteral = 2048, - ESSymbol = 4096, - UniqueESSymbol = 8192, - Void = 16384, - Undefined = 32768, - Null = 65536, - Never = 131072, - TypeParameter = 262144, - Object = 524288, - Union = 1048576, - Intersection = 2097152, - Index = 4194304, - IndexedAccess = 8388608, - Conditional = 16777216, - Substitution = 33554432, - NonPrimitive = 67108864, - TemplateLiteral = 134217728, - StringMapping = 268435456, - Literal = 2944, - Unit = 109440, - StringOrNumberLiteral = 384, - PossiblyFalsy = 117724, - StringLike = 402653316, - NumberLike = 296, - BigIntLike = 2112, - BooleanLike = 528, - EnumLike = 1056, - ESSymbolLike = 12288, - VoidLike = 49152, - UnionOrIntersection = 3145728, - StructuredType = 3670016, - TypeVariable = 8650752, - InstantiableNonPrimitive = 58982400, - InstantiablePrimitive = 406847488, - Instantiable = 465829888, - StructuredOrInstantiable = 469499904, - Narrowable = 536624127 - } + type TypeFlags = (typeof TypeFlags)[keyof typeof TypeFlags]; + const TypeFlags: { + Any: bigint; + Unknown: bigint; + String: bigint; + Number: bigint; + Boolean: bigint; + Enum: bigint; + BigInt: bigint; + StringLiteral: bigint; + NumberLiteral: bigint; + BooleanLiteral: bigint; + EnumLiteral: bigint; + BigIntLiteral: bigint; + ESSymbol: bigint; + UniqueESSymbol: bigint; + Void: bigint; + Undefined: bigint; + Null: bigint; + Never: bigint; + TypeParameter: bigint; + Object: bigint; + Union: bigint; + Intersection: bigint; + Index: bigint; + IndexedAccess: bigint; + Conditional: bigint; + Substitution: bigint; + NonPrimitive: bigint; + TemplateLiteral: bigint; + StringMapping: bigint; + Self: bigint; + Selfed: bigint; + NeverWithError: bigint; + Print: bigint; + /** @internal */ + AnyOrUnknown: bigint; + /** @internal */ + Nullable: bigint; + Literal: bigint; + Unit: bigint; + StringOrNumberLiteral: bigint; + /** @internal */ + StringOrNumberLiteralOrUnique: bigint; + /** @internal */ + DefinitelyFalsy: bigint; + PossiblyFalsy: bigint; + /** @internal */ + Intrinsic: bigint; + /** @internal */ + Primitive: bigint; + StringLike: bigint; + NumberLike: bigint; + BigIntLike: bigint; + BooleanLike: bigint; + EnumLike: bigint; + ESSymbolLike: bigint; + VoidLike: bigint; + /** @internal */ + DefinitelyNonNullable: bigint; + /** @internal */ + DisjointDomains: bigint; + UnionOrIntersection: bigint; + StructuredType: bigint; + TypeVariable: bigint; + InstantiableNonPrimitive: bigint; + InstantiablePrimitive: bigint; + Instantiable: bigint; + StructuredOrInstantiable: bigint; + /** @internal */ + ObjectFlagsType: bigint; + /** @internal */ + Simplifiable: bigint; + /** @internal */ + Singleton: bigint; + Narrowable: bigint; + /** @internal */ + IncludesMask: bigint; + /** @internal */ + IncludesMissingType: bigint; + /** @internal */ + IncludesNonWideningType: bigint; + /** @internal */ + IncludesWildcard: bigint; + /** @internal */ + IncludesEmptyObject: bigint; + /** @internal */ + IncludesInstantiable: bigint; + /** @internal */ + NotPrimitiveUnion: bigint; + }; type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; interface Type { flags: TypeFlags; @@ -6877,6 +6921,16 @@ declare namespace ts { baseType: Type; constraint: Type; } + interface SelfedType extends InstantiableType { + type: Type; + selfType: Type; + instantiations: Map; + } + interface PrintType extends InstantiableType { + type: Type; + flagType: Type; + resolvedStringLiteralType: StringLiteralType; + } enum SignatureKind { Call = 0, Construct = 1 @@ -7419,7 +7473,8 @@ declare namespace ts { NoHoisting = 4194304, HasEndOfDeclarationMarker = 8388608, Iterator = 16777216, - NoAsciiEscaping = 33554432 + NoAsciiEscaping = 33554432, + NoStringEscaping = -2147483648 } interface EmitHelperBase { readonly name: string; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 7c3088b485c5d..d01a8c9e23726 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -212,217 +212,218 @@ declare namespace ts { ObjectKeyword = 149, SatisfiesKeyword = 150, SetKeyword = 151, - StringKeyword = 152, - SymbolKeyword = 153, - TypeKeyword = 154, - UndefinedKeyword = 155, - UniqueKeyword = 156, - UnknownKeyword = 157, - FromKeyword = 158, - GlobalKeyword = 159, - BigIntKeyword = 160, - OverrideKeyword = 161, - OfKeyword = 162, - QualifiedName = 163, - ComputedPropertyName = 164, - TypeParameter = 165, - Parameter = 166, - Decorator = 167, - PropertySignature = 168, - PropertyDeclaration = 169, - MethodSignature = 170, - MethodDeclaration = 171, - ClassStaticBlockDeclaration = 172, - Constructor = 173, - GetAccessor = 174, - SetAccessor = 175, - CallSignature = 176, - ConstructSignature = 177, - IndexSignature = 178, - TypePredicate = 179, - TypeReference = 180, - FunctionType = 181, - ConstructorType = 182, - TypeQuery = 183, - TypeLiteral = 184, - ArrayType = 185, - TupleType = 186, - OptionalType = 187, - RestType = 188, - UnionType = 189, - IntersectionType = 190, - ConditionalType = 191, - InferType = 192, - ParenthesizedType = 193, - ThisType = 194, - TypeOperator = 195, - IndexedAccessType = 196, - MappedType = 197, - LiteralType = 198, - NamedTupleMember = 199, - TemplateLiteralType = 200, - TemplateLiteralTypeSpan = 201, - ImportType = 202, - ObjectBindingPattern = 203, - ArrayBindingPattern = 204, - BindingElement = 205, - ArrayLiteralExpression = 206, - ObjectLiteralExpression = 207, - PropertyAccessExpression = 208, - ElementAccessExpression = 209, - CallExpression = 210, - NewExpression = 211, - TaggedTemplateExpression = 212, - TypeAssertionExpression = 213, - ParenthesizedExpression = 214, - FunctionExpression = 215, - ArrowFunction = 216, - DeleteExpression = 217, - TypeOfExpression = 218, - VoidExpression = 219, - AwaitExpression = 220, - PrefixUnaryExpression = 221, - PostfixUnaryExpression = 222, - BinaryExpression = 223, - ConditionalExpression = 224, - TemplateExpression = 225, - YieldExpression = 226, - SpreadElement = 227, - ClassExpression = 228, - OmittedExpression = 229, - ExpressionWithTypeArguments = 230, - AsExpression = 231, - NonNullExpression = 232, - MetaProperty = 233, - SyntheticExpression = 234, - SatisfiesExpression = 235, - TemplateSpan = 236, - SemicolonClassElement = 237, - Block = 238, - EmptyStatement = 239, - VariableStatement = 240, - ExpressionStatement = 241, - IfStatement = 242, - DoStatement = 243, - WhileStatement = 244, - ForStatement = 245, - ForInStatement = 246, - ForOfStatement = 247, - ContinueStatement = 248, - BreakStatement = 249, - ReturnStatement = 250, - WithStatement = 251, - SwitchStatement = 252, - LabeledStatement = 253, - ThrowStatement = 254, - TryStatement = 255, - DebuggerStatement = 256, - VariableDeclaration = 257, - VariableDeclarationList = 258, - FunctionDeclaration = 259, - ClassDeclaration = 260, - InterfaceDeclaration = 261, - TypeAliasDeclaration = 262, - EnumDeclaration = 263, - ModuleDeclaration = 264, - ModuleBlock = 265, - CaseBlock = 266, - NamespaceExportDeclaration = 267, - ImportEqualsDeclaration = 268, - ImportDeclaration = 269, - ImportClause = 270, - NamespaceImport = 271, - NamedImports = 272, - ImportSpecifier = 273, - ExportAssignment = 274, - ExportDeclaration = 275, - NamedExports = 276, - NamespaceExport = 277, - ExportSpecifier = 278, - MissingDeclaration = 279, - ExternalModuleReference = 280, - JsxElement = 281, - JsxSelfClosingElement = 282, - JsxOpeningElement = 283, - JsxClosingElement = 284, - JsxFragment = 285, - JsxOpeningFragment = 286, - JsxClosingFragment = 287, - JsxAttribute = 288, - JsxAttributes = 289, - JsxSpreadAttribute = 290, - JsxExpression = 291, - CaseClause = 292, - DefaultClause = 293, - HeritageClause = 294, - CatchClause = 295, - AssertClause = 296, - AssertEntry = 297, - ImportTypeAssertionContainer = 298, - PropertyAssignment = 299, - ShorthandPropertyAssignment = 300, - SpreadAssignment = 301, - EnumMember = 302, - UnparsedPrologue = 303, - UnparsedPrepend = 304, - UnparsedText = 305, - UnparsedInternalText = 306, - UnparsedSyntheticReference = 307, - SourceFile = 308, - Bundle = 309, - UnparsedSource = 310, - InputFiles = 311, - JSDocTypeExpression = 312, - JSDocNameReference = 313, - JSDocMemberName = 314, - JSDocAllType = 315, - JSDocUnknownType = 316, - JSDocNullableType = 317, - JSDocNonNullableType = 318, - JSDocOptionalType = 319, - JSDocFunctionType = 320, - JSDocVariadicType = 321, - JSDocNamepathType = 322, - JSDoc = 323, + SelfKeyword = 152, + StringKeyword = 153, + SymbolKeyword = 154, + TypeKeyword = 155, + UndefinedKeyword = 156, + UniqueKeyword = 157, + UnknownKeyword = 158, + FromKeyword = 159, + GlobalKeyword = 160, + BigIntKeyword = 161, + OverrideKeyword = 162, + OfKeyword = 163, + QualifiedName = 164, + ComputedPropertyName = 165, + TypeParameter = 166, + Parameter = 167, + Decorator = 168, + PropertySignature = 169, + PropertyDeclaration = 170, + MethodSignature = 171, + MethodDeclaration = 172, + ClassStaticBlockDeclaration = 173, + Constructor = 174, + GetAccessor = 175, + SetAccessor = 176, + CallSignature = 177, + ConstructSignature = 178, + IndexSignature = 179, + TypePredicate = 180, + TypeReference = 181, + FunctionType = 182, + ConstructorType = 183, + TypeQuery = 184, + TypeLiteral = 185, + ArrayType = 186, + TupleType = 187, + OptionalType = 188, + RestType = 189, + UnionType = 190, + IntersectionType = 191, + ConditionalType = 192, + InferType = 193, + ParenthesizedType = 194, + ThisType = 195, + TypeOperator = 196, + IndexedAccessType = 197, + MappedType = 198, + LiteralType = 199, + NamedTupleMember = 200, + TemplateLiteralType = 201, + TemplateLiteralTypeSpan = 202, + ImportType = 203, + ObjectBindingPattern = 204, + ArrayBindingPattern = 205, + BindingElement = 206, + ArrayLiteralExpression = 207, + ObjectLiteralExpression = 208, + PropertyAccessExpression = 209, + ElementAccessExpression = 210, + CallExpression = 211, + NewExpression = 212, + TaggedTemplateExpression = 213, + TypeAssertionExpression = 214, + ParenthesizedExpression = 215, + FunctionExpression = 216, + ArrowFunction = 217, + DeleteExpression = 218, + TypeOfExpression = 219, + VoidExpression = 220, + AwaitExpression = 221, + PrefixUnaryExpression = 222, + PostfixUnaryExpression = 223, + BinaryExpression = 224, + ConditionalExpression = 225, + TemplateExpression = 226, + YieldExpression = 227, + SpreadElement = 228, + ClassExpression = 229, + OmittedExpression = 230, + ExpressionWithTypeArguments = 231, + AsExpression = 232, + NonNullExpression = 233, + MetaProperty = 234, + SyntheticExpression = 235, + SatisfiesExpression = 236, + TemplateSpan = 237, + SemicolonClassElement = 238, + Block = 239, + EmptyStatement = 240, + VariableStatement = 241, + ExpressionStatement = 242, + IfStatement = 243, + DoStatement = 244, + WhileStatement = 245, + ForStatement = 246, + ForInStatement = 247, + ForOfStatement = 248, + ContinueStatement = 249, + BreakStatement = 250, + ReturnStatement = 251, + WithStatement = 252, + SwitchStatement = 253, + LabeledStatement = 254, + ThrowStatement = 255, + TryStatement = 256, + DebuggerStatement = 257, + VariableDeclaration = 258, + VariableDeclarationList = 259, + FunctionDeclaration = 260, + ClassDeclaration = 261, + InterfaceDeclaration = 262, + TypeAliasDeclaration = 263, + EnumDeclaration = 264, + ModuleDeclaration = 265, + ModuleBlock = 266, + CaseBlock = 267, + NamespaceExportDeclaration = 268, + ImportEqualsDeclaration = 269, + ImportDeclaration = 270, + ImportClause = 271, + NamespaceImport = 272, + NamedImports = 273, + ImportSpecifier = 274, + ExportAssignment = 275, + ExportDeclaration = 276, + NamedExports = 277, + NamespaceExport = 278, + ExportSpecifier = 279, + MissingDeclaration = 280, + ExternalModuleReference = 281, + JsxElement = 282, + JsxSelfClosingElement = 283, + JsxOpeningElement = 284, + JsxClosingElement = 285, + JsxFragment = 286, + JsxOpeningFragment = 287, + JsxClosingFragment = 288, + JsxAttribute = 289, + JsxAttributes = 290, + JsxSpreadAttribute = 291, + JsxExpression = 292, + CaseClause = 293, + DefaultClause = 294, + HeritageClause = 295, + CatchClause = 296, + AssertClause = 297, + AssertEntry = 298, + ImportTypeAssertionContainer = 299, + PropertyAssignment = 300, + ShorthandPropertyAssignment = 301, + SpreadAssignment = 302, + EnumMember = 303, + UnparsedPrologue = 304, + UnparsedPrepend = 305, + UnparsedText = 306, + UnparsedInternalText = 307, + UnparsedSyntheticReference = 308, + SourceFile = 309, + Bundle = 310, + UnparsedSource = 311, + InputFiles = 312, + JSDocTypeExpression = 313, + JSDocNameReference = 314, + JSDocMemberName = 315, + JSDocAllType = 316, + JSDocUnknownType = 317, + JSDocNullableType = 318, + JSDocNonNullableType = 319, + JSDocOptionalType = 320, + JSDocFunctionType = 321, + JSDocVariadicType = 322, + JSDocNamepathType = 323, + JSDoc = 324, /** @deprecated Use SyntaxKind.JSDoc */ - JSDocComment = 323, - JSDocText = 324, - JSDocTypeLiteral = 325, - JSDocSignature = 326, - JSDocLink = 327, - JSDocLinkCode = 328, - JSDocLinkPlain = 329, - JSDocTag = 330, - JSDocAugmentsTag = 331, - JSDocImplementsTag = 332, - JSDocAuthorTag = 333, - JSDocDeprecatedTag = 334, - JSDocClassTag = 335, - JSDocPublicTag = 336, - JSDocPrivateTag = 337, - JSDocProtectedTag = 338, - JSDocReadonlyTag = 339, - JSDocOverrideTag = 340, - JSDocCallbackTag = 341, - JSDocOverloadTag = 342, - JSDocEnumTag = 343, - JSDocParameterTag = 344, - JSDocReturnTag = 345, - JSDocThisTag = 346, - JSDocTypeTag = 347, - JSDocTemplateTag = 348, - JSDocTypedefTag = 349, - JSDocSeeTag = 350, - JSDocPropertyTag = 351, - JSDocThrowsTag = 352, - SyntaxList = 353, - NotEmittedStatement = 354, - PartiallyEmittedExpression = 355, - CommaListExpression = 356, - MergeDeclarationMarker = 357, - EndOfDeclarationMarker = 358, - SyntheticReferenceExpression = 359, - Count = 360, + JSDocComment = 324, + JSDocText = 325, + JSDocTypeLiteral = 326, + JSDocSignature = 327, + JSDocLink = 328, + JSDocLinkCode = 329, + JSDocLinkPlain = 330, + JSDocTag = 331, + JSDocAugmentsTag = 332, + JSDocImplementsTag = 333, + JSDocAuthorTag = 334, + JSDocDeprecatedTag = 335, + JSDocClassTag = 336, + JSDocPublicTag = 337, + JSDocPrivateTag = 338, + JSDocProtectedTag = 339, + JSDocReadonlyTag = 340, + JSDocOverrideTag = 341, + JSDocCallbackTag = 342, + JSDocOverloadTag = 343, + JSDocEnumTag = 344, + JSDocParameterTag = 345, + JSDocReturnTag = 346, + JSDocThisTag = 347, + JSDocTypeTag = 348, + JSDocTemplateTag = 349, + JSDocTypedefTag = 350, + JSDocSeeTag = 351, + JSDocPropertyTag = 352, + JSDocThrowsTag = 353, + SyntaxList = 354, + NotEmittedStatement = 355, + PartiallyEmittedExpression = 356, + CommaListExpression = 357, + MergeDeclarationMarker = 358, + EndOfDeclarationMarker = 359, + SyntheticReferenceExpression = 360, + Count = 361, FirstAssignment = 63, LastAssignment = 78, FirstCompoundAssignment = 64, @@ -430,15 +431,15 @@ declare namespace ts { FirstReservedWord = 81, LastReservedWord = 116, FirstKeyword = 81, - LastKeyword = 162, + LastKeyword = 163, FirstFutureReservedWord = 117, LastFutureReservedWord = 125, - FirstTypeNode = 179, - LastTypeNode = 202, + FirstTypeNode = 180, + LastTypeNode = 203, FirstPunctuation = 18, LastPunctuation = 78, FirstToken = 0, - LastToken = 162, + LastToken = 163, FirstTriviaToken = 2, LastTriviaToken = 7, FirstLiteralToken = 8, @@ -447,21 +448,21 @@ declare namespace ts { LastTemplateToken = 17, FirstBinaryOperator = 29, LastBinaryOperator = 78, - FirstStatement = 240, - LastStatement = 256, - FirstNode = 163, - FirstJSDocNode = 312, - LastJSDocNode = 352, - FirstJSDocTagNode = 330, - LastJSDocTagNode = 352 + FirstStatement = 241, + LastStatement = 257, + FirstNode = 164, + FirstJSDocNode = 313, + LastJSDocNode = 353, + FirstJSDocTagNode = 331, + LastJSDocTagNode = 353 } type TriviaSyntaxKind = SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia | SyntaxKind.NewLineTrivia | SyntaxKind.WhitespaceTrivia | SyntaxKind.ShebangTrivia | SyntaxKind.ConflictMarkerTrivia; type LiteralSyntaxKind = SyntaxKind.NumericLiteral | SyntaxKind.BigIntLiteral | SyntaxKind.StringLiteral | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.RegularExpressionLiteral | SyntaxKind.NoSubstitutionTemplateLiteral; type PseudoLiteralSyntaxKind = SyntaxKind.TemplateHead | SyntaxKind.TemplateMiddle | SyntaxKind.TemplateTail; type PunctuationSyntaxKind = SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.OpenParenToken | SyntaxKind.CloseParenToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.DotToken | SyntaxKind.DotDotDotToken | SyntaxKind.SemicolonToken | SyntaxKind.CommaToken | SyntaxKind.QuestionDotToken | SyntaxKind.LessThanToken | SyntaxKind.LessThanSlashToken | SyntaxKind.GreaterThanToken | SyntaxKind.LessThanEqualsToken | SyntaxKind.GreaterThanEqualsToken | SyntaxKind.EqualsEqualsToken | SyntaxKind.ExclamationEqualsToken | SyntaxKind.EqualsEqualsEqualsToken | SyntaxKind.ExclamationEqualsEqualsToken | SyntaxKind.EqualsGreaterThanToken | SyntaxKind.PlusToken | SyntaxKind.MinusToken | SyntaxKind.AsteriskToken | SyntaxKind.AsteriskAsteriskToken | SyntaxKind.SlashToken | SyntaxKind.PercentToken | SyntaxKind.PlusPlusToken | SyntaxKind.MinusMinusToken | SyntaxKind.LessThanLessThanToken | SyntaxKind.GreaterThanGreaterThanToken | SyntaxKind.GreaterThanGreaterThanGreaterThanToken | SyntaxKind.AmpersandToken | SyntaxKind.BarToken | SyntaxKind.CaretToken | SyntaxKind.ExclamationToken | SyntaxKind.TildeToken | SyntaxKind.AmpersandAmpersandToken | SyntaxKind.BarBarToken | SyntaxKind.QuestionQuestionToken | SyntaxKind.QuestionToken | SyntaxKind.ColonToken | SyntaxKind.AtToken | SyntaxKind.BacktickToken | SyntaxKind.HashToken | SyntaxKind.EqualsToken | SyntaxKind.PlusEqualsToken | SyntaxKind.MinusEqualsToken | SyntaxKind.AsteriskEqualsToken | SyntaxKind.AsteriskAsteriskEqualsToken | SyntaxKind.SlashEqualsToken | SyntaxKind.PercentEqualsToken | SyntaxKind.LessThanLessThanEqualsToken | SyntaxKind.GreaterThanGreaterThanEqualsToken | SyntaxKind.GreaterThanGreaterThanGreaterThanEqualsToken | SyntaxKind.AmpersandEqualsToken | SyntaxKind.BarEqualsToken | SyntaxKind.CaretEqualsToken; - type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AccessorKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AssertKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OutKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SatisfiesKeyword | SyntaxKind.SetKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword; + type KeywordSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AccessorKeyword | SyntaxKind.AnyKeyword | SyntaxKind.AsKeyword | SyntaxKind.AssertsKeyword | SyntaxKind.AssertKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.AwaitKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.BreakKeyword | SyntaxKind.CaseKeyword | SyntaxKind.CatchKeyword | SyntaxKind.ClassKeyword | SyntaxKind.ConstKeyword | SyntaxKind.ConstructorKeyword | SyntaxKind.ContinueKeyword | SyntaxKind.DebuggerKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.DeleteKeyword | SyntaxKind.DoKeyword | SyntaxKind.ElseKeyword | SyntaxKind.EnumKeyword | SyntaxKind.ExportKeyword | SyntaxKind.ExtendsKeyword | SyntaxKind.FalseKeyword | SyntaxKind.FinallyKeyword | SyntaxKind.ForKeyword | SyntaxKind.FromKeyword | SyntaxKind.FunctionKeyword | SyntaxKind.GetKeyword | SyntaxKind.GlobalKeyword | SyntaxKind.IfKeyword | SyntaxKind.ImplementsKeyword | SyntaxKind.ImportKeyword | SyntaxKind.InferKeyword | SyntaxKind.InKeyword | SyntaxKind.InstanceOfKeyword | SyntaxKind.InterfaceKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.IsKeyword | SyntaxKind.KeyOfKeyword | SyntaxKind.LetKeyword | SyntaxKind.ModuleKeyword | SyntaxKind.NamespaceKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NewKeyword | SyntaxKind.NullKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.OfKeyword | SyntaxKind.PackageKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OutKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.RequireKeyword | SyntaxKind.ReturnKeyword | SyntaxKind.SatisfiesKeyword | SyntaxKind.SetKeyword | SyntaxKind.SelfKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword | SyntaxKind.SwitchKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.ThisKeyword | SyntaxKind.ThrowKeyword | SyntaxKind.TrueKeyword | SyntaxKind.TryKeyword | SyntaxKind.TypeKeyword | SyntaxKind.TypeOfKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UniqueKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VarKeyword | SyntaxKind.VoidKeyword | SyntaxKind.WhileKeyword | SyntaxKind.WithKeyword | SyntaxKind.YieldKeyword; type ModifierSyntaxKind = SyntaxKind.AbstractKeyword | SyntaxKind.AccessorKeyword | SyntaxKind.AsyncKeyword | SyntaxKind.ConstKeyword | SyntaxKind.DeclareKeyword | SyntaxKind.DefaultKeyword | SyntaxKind.ExportKeyword | SyntaxKind.InKeyword | SyntaxKind.PrivateKeyword | SyntaxKind.ProtectedKeyword | SyntaxKind.PublicKeyword | SyntaxKind.ReadonlyKeyword | SyntaxKind.OutKeyword | SyntaxKind.OverrideKeyword | SyntaxKind.StaticKeyword; - type KeywordTypeSyntaxKind = SyntaxKind.AnyKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.VoidKeyword; + type KeywordTypeSyntaxKind = SyntaxKind.AnyKeyword | SyntaxKind.BigIntKeyword | SyntaxKind.BooleanKeyword | SyntaxKind.IntrinsicKeyword | SyntaxKind.NeverKeyword | SyntaxKind.NumberKeyword | SyntaxKind.ObjectKeyword | SyntaxKind.StringKeyword | SyntaxKind.SymbolKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UnknownKeyword | SyntaxKind.SelfKeyword | SyntaxKind.VoidKeyword; type TokenSyntaxKind = SyntaxKind.Unknown | SyntaxKind.EndOfFileToken | TriviaSyntaxKind | LiteralSyntaxKind | PseudoLiteralSyntaxKind | PunctuationSyntaxKind | SyntaxKind.Identifier | KeywordSyntaxKind; type JsxTokenSyntaxKind = SyntaxKind.LessThanSlashToken | SyntaxKind.EndOfFileToken | SyntaxKind.ConflictMarkerTrivia | SyntaxKind.JsxText | SyntaxKind.JsxTextAllWhiteSpaces | SyntaxKind.OpenBraceToken | SyntaxKind.LessThanToken; type JSDocSyntaxKind = SyntaxKind.EndOfFileToken | SyntaxKind.WhitespaceTrivia | SyntaxKind.AtToken | SyntaxKind.NewLineTrivia | SyntaxKind.AsteriskToken | SyntaxKind.OpenBraceToken | SyntaxKind.CloseBraceToken | SyntaxKind.LessThanToken | SyntaxKind.GreaterThanToken | SyntaxKind.OpenBracketToken | SyntaxKind.CloseBracketToken | SyntaxKind.EqualsToken | SyntaxKind.CommaToken | SyntaxKind.DotToken | SyntaxKind.Identifier | SyntaxKind.BacktickToken | SyntaxKind.HashToken | SyntaxKind.Unknown | KeywordSyntaxKind; @@ -2493,6 +2494,7 @@ declare namespace ts { UseSingleQuotesForStringLiteralType = 268435456, NoTypeReduction = 536870912, OmitThisParameter = 33554432, + NoStringLiteralEscaping = -2147483648, AllowThisInObjectLiteral = 32768, AllowQualifiedNameInPlaceOfIdentifier = 65536, /** @deprecated AllowQualifedNameInPlaceOfIdentifier. Use AllowQualifiedNameInPlaceOfIdentifier instead. */ @@ -2531,8 +2533,9 @@ declare namespace ts { InElementType = 2097152, InFirstTypeArgument = 4194304, InTypeAlias = 8388608, + NoStringLiteralEscaping = -2147483648, /** @deprecated */ WriteOwnNameForAnyLike = 0, - NodeBuilderFlagsMask = 848330091 + NodeBuilderFlagsMask = -1299153557 } enum SymbolFormatFlags { None = 0, @@ -2696,56 +2699,97 @@ declare namespace ts { } /** SymbolTable based on ES6 Map interface. */ type SymbolTable = UnderscoreEscapedMap; - enum TypeFlags { - Any = 1, - Unknown = 2, - String = 4, - Number = 8, - Boolean = 16, - Enum = 32, - BigInt = 64, - StringLiteral = 128, - NumberLiteral = 256, - BooleanLiteral = 512, - EnumLiteral = 1024, - BigIntLiteral = 2048, - ESSymbol = 4096, - UniqueESSymbol = 8192, - Void = 16384, - Undefined = 32768, - Null = 65536, - Never = 131072, - TypeParameter = 262144, - Object = 524288, - Union = 1048576, - Intersection = 2097152, - Index = 4194304, - IndexedAccess = 8388608, - Conditional = 16777216, - Substitution = 33554432, - NonPrimitive = 67108864, - TemplateLiteral = 134217728, - StringMapping = 268435456, - Literal = 2944, - Unit = 109440, - StringOrNumberLiteral = 384, - PossiblyFalsy = 117724, - StringLike = 402653316, - NumberLike = 296, - BigIntLike = 2112, - BooleanLike = 528, - EnumLike = 1056, - ESSymbolLike = 12288, - VoidLike = 49152, - UnionOrIntersection = 3145728, - StructuredType = 3670016, - TypeVariable = 8650752, - InstantiableNonPrimitive = 58982400, - InstantiablePrimitive = 406847488, - Instantiable = 465829888, - StructuredOrInstantiable = 469499904, - Narrowable = 536624127 - } + type TypeFlags = (typeof TypeFlags)[keyof typeof TypeFlags]; + const TypeFlags: { + Any: bigint; + Unknown: bigint; + String: bigint; + Number: bigint; + Boolean: bigint; + Enum: bigint; + BigInt: bigint; + StringLiteral: bigint; + NumberLiteral: bigint; + BooleanLiteral: bigint; + EnumLiteral: bigint; + BigIntLiteral: bigint; + ESSymbol: bigint; + UniqueESSymbol: bigint; + Void: bigint; + Undefined: bigint; + Null: bigint; + Never: bigint; + TypeParameter: bigint; + Object: bigint; + Union: bigint; + Intersection: bigint; + Index: bigint; + IndexedAccess: bigint; + Conditional: bigint; + Substitution: bigint; + NonPrimitive: bigint; + TemplateLiteral: bigint; + StringMapping: bigint; + Self: bigint; + Selfed: bigint; + NeverWithError: bigint; + Print: bigint; + /** @internal */ + AnyOrUnknown: bigint; + /** @internal */ + Nullable: bigint; + Literal: bigint; + Unit: bigint; + StringOrNumberLiteral: bigint; + /** @internal */ + StringOrNumberLiteralOrUnique: bigint; + /** @internal */ + DefinitelyFalsy: bigint; + PossiblyFalsy: bigint; + /** @internal */ + Intrinsic: bigint; + /** @internal */ + Primitive: bigint; + StringLike: bigint; + NumberLike: bigint; + BigIntLike: bigint; + BooleanLike: bigint; + EnumLike: bigint; + ESSymbolLike: bigint; + VoidLike: bigint; + /** @internal */ + DefinitelyNonNullable: bigint; + /** @internal */ + DisjointDomains: bigint; + UnionOrIntersection: bigint; + StructuredType: bigint; + TypeVariable: bigint; + InstantiableNonPrimitive: bigint; + InstantiablePrimitive: bigint; + Instantiable: bigint; + StructuredOrInstantiable: bigint; + /** @internal */ + ObjectFlagsType: bigint; + /** @internal */ + Simplifiable: bigint; + /** @internal */ + Singleton: bigint; + Narrowable: bigint; + /** @internal */ + IncludesMask: bigint; + /** @internal */ + IncludesMissingType: bigint; + /** @internal */ + IncludesNonWideningType: bigint; + /** @internal */ + IncludesWildcard: bigint; + /** @internal */ + IncludesEmptyObject: bigint; + /** @internal */ + IncludesInstantiable: bigint; + /** @internal */ + NotPrimitiveUnion: bigint; + }; type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; interface Type { flags: TypeFlags; @@ -2942,6 +2986,16 @@ declare namespace ts { baseType: Type; constraint: Type; } + interface SelfedType extends InstantiableType { + type: Type; + selfType: Type; + instantiations: Map; + } + interface PrintType extends InstantiableType { + type: Type; + flagType: Type; + resolvedStringLiteralType: StringLiteralType; + } enum SignatureKind { Call = 0, Construct = 1 @@ -3484,7 +3538,8 @@ declare namespace ts { NoHoisting = 4194304, HasEndOfDeclarationMarker = 8388608, Iterator = 16777216, - NoAsciiEscaping = 33554432 + NoAsciiEscaping = 33554432, + NoStringEscaping = -2147483648 } interface EmitHelperBase { readonly name: string; diff --git a/tests/baselines/reference/completionsCommentsClass.baseline b/tests/baselines/reference/completionsCommentsClass.baseline index a550ca56675ac..d8151649813aa 100644 --- a/tests/baselines/reference/completionsCommentsClass.baseline +++ b/tests/baselines/reference/completionsCommentsClass.baseline @@ -3127,6 +3127,18 @@ } ] }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15", + "displayParts": [ + { + "text": "self", + "kind": "keyword" + } + ] + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/completionsCommentsClassMembers.baseline b/tests/baselines/reference/completionsCommentsClassMembers.baseline index 2f7c8f4303da9..7578664af6415 100644 --- a/tests/baselines/reference/completionsCommentsClassMembers.baseline +++ b/tests/baselines/reference/completionsCommentsClassMembers.baseline @@ -86404,6 +86404,18 @@ } ] }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15", + "displayParts": [ + { + "text": "self", + "kind": "keyword" + } + ] + }, { "name": "string", "kind": "keyword", @@ -91774,6 +91786,18 @@ } ] }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15", + "displayParts": [ + { + "text": "self", + "kind": "keyword" + } + ] + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/completionsCommentsCommentParsing.baseline b/tests/baselines/reference/completionsCommentsCommentParsing.baseline index 2d826f426fa8d..e27bed19c6f13 100644 --- a/tests/baselines/reference/completionsCommentsCommentParsing.baseline +++ b/tests/baselines/reference/completionsCommentsCommentParsing.baseline @@ -22675,6 +22675,18 @@ } ] }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15", + "displayParts": [ + { + "text": "self", + "kind": "keyword" + } + ] + }, { "name": "string", "kind": "keyword", @@ -40623,6 +40635,18 @@ } ] }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15", + "displayParts": [ + { + "text": "self", + "kind": "keyword" + } + ] + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/completionsCommentsFunctionExpression.baseline b/tests/baselines/reference/completionsCommentsFunctionExpression.baseline index 7a354bdbd0513..e16b04be15137 100644 --- a/tests/baselines/reference/completionsCommentsFunctionExpression.baseline +++ b/tests/baselines/reference/completionsCommentsFunctionExpression.baseline @@ -3034,6 +3034,18 @@ } ] }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15", + "displayParts": [ + { + "text": "self", + "kind": "keyword" + } + ] + }, { "name": "string", "kind": "keyword", @@ -7493,6 +7505,18 @@ } ] }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15", + "displayParts": [ + { + "text": "self", + "kind": "keyword" + } + ] + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/self-types-case-insensitive.errors.txt b/tests/baselines/reference/self-types-case-insensitive.errors.txt new file mode 100644 index 0000000000000..3a2087029999a --- /dev/null +++ b/tests/baselines/reference/self-types-case-insensitive.errors.txt @@ -0,0 +1,50 @@ +tests/cases/compiler/self-types-case-insensitive.ts(18,11): error TS18051: Type '"Acept"' is not assignable to type 'CaseInsensitive<"Set-Cookie" | "Accept">' + Type 'Lowercase<"Acept">' is not assignable to 'Lowercase<"Set-Cookie" | "Accept">' + Type '"acept"' is not assignable to '"set-cookie" | "accept"' +tests/cases/compiler/self-types-case-insensitive.ts(32,3): error TS2322: Type '{ "Set-Cookie": string; }' is not assignable to type 'Headers'. + Object literal may only specify known properties, and '"Set-Cookie"' does not exist in type 'Headers'. + + +==== tests/cases/compiler/self-types-case-insensitive.ts (2 errors) ==== + type CaseInsensitive = + self extends string + ? Lowercase extends Lowercase + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'CaseInsensitive<${Print}>'`, + `Type 'Lowercase<${Print}>' is not assignable to 'Lowercase<${Print}>'`, + `Type '${Print>}' is not assignable to '${Print>}'` + ]> + : T + + declare const setHeader: + (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void + + setHeader("Set-Cookie", "test") + setHeader("Accept", "test2") + setHeader("sEt-cOoKiE", "stop writing headers like this but ok") + setHeader("Acept", "nah this has a typo") + ~~~~~~~ +!!! error TS18051: Type '"Acept"' is not assignable to type 'CaseInsensitive<"Set-Cookie" | "Accept">' +!!! error TS18051: Type 'Lowercase<"Acept">' is not assignable to 'Lowercase<"Set-Cookie" | "Accept">' +!!! error TS18051: Type '"acept"' is not assignable to '"set-cookie" | "accept"' + + // TODO?: the autocompletion doesn't work, although it could be doable by + // instantiating `self` with `unknown`, at least in this case. + // Or by an alternative definition... + // type CaseInsensitive = T | [existing-defintion] + // the autocompletion works now but the custom error message doesn't + // get shown + + type Headers = + Record, string> + + let headers: Headers = { + // TODO: this is not an excess property, should compile + "Set-Cookie": "test" + ~~~~~~~~~~~~~~~~~~~~ +!!! error TS2322: Type '{ "Set-Cookie": string; }' is not assignable to type 'Headers'. +!!! error TS2322: Object literal may only specify known properties, and '"Set-Cookie"' does not exist in type 'Headers'. + } + + export {} \ No newline at end of file diff --git a/tests/baselines/reference/self-types-case-insensitive.js b/tests/baselines/reference/self-types-case-insensitive.js new file mode 100644 index 0000000000000..b4d0c2a3955a6 --- /dev/null +++ b/tests/baselines/reference/self-types-case-insensitive.js @@ -0,0 +1,48 @@ +//// [self-types-case-insensitive.ts] +type CaseInsensitive = + self extends string + ? Lowercase extends Lowercase + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'CaseInsensitive<${Print}>'`, + `Type 'Lowercase<${Print}>' is not assignable to 'Lowercase<${Print}>'`, + `Type '${Print>}' is not assignable to '${Print>}'` + ]> + : T + +declare const setHeader: + (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void + +setHeader("Set-Cookie", "test") +setHeader("Accept", "test2") +setHeader("sEt-cOoKiE", "stop writing headers like this but ok") +setHeader("Acept", "nah this has a typo") + +// TODO?: the autocompletion doesn't work, although it could be doable by +// instantiating `self` with `unknown`, at least in this case. +// Or by an alternative definition... +// type CaseInsensitive = T | [existing-defintion] +// the autocompletion works now but the custom error message doesn't +// get shown + +type Headers = + Record, string> + +let headers: Headers = { + // TODO: this is not an excess property, should compile + "Set-Cookie": "test" +} + +export {} + +//// [self-types-case-insensitive.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +setHeader("Set-Cookie", "test"); +setHeader("Accept", "test2"); +setHeader("sEt-cOoKiE", "stop writing headers like this but ok"); +setHeader("Acept", "nah this has a typo"); +var headers = { + // TODO: this is not an excess property, should compile + "Set-Cookie": "test" +}; diff --git a/tests/baselines/reference/self-types-case-insensitive.symbols b/tests/baselines/reference/self-types-case-insensitive.symbols new file mode 100644 index 0000000000000..57b0757d69e32 --- /dev/null +++ b/tests/baselines/reference/self-types-case-insensitive.symbols @@ -0,0 +1,80 @@ +=== tests/cases/compiler/self-types-case-insensitive.ts === +type CaseInsensitive = +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-case-insensitive.ts, 0, 0)) +>T : Symbol(T, Decl(self-types-case-insensitive.ts, 0, 21)) + + self extends string + ? Lowercase extends Lowercase +>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --)) +>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-case-insensitive.ts, 0, 21)) + + ? self + : Never<[ +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) + + `Type '${Print}' is not assignable to type 'CaseInsensitive<${Print}>'`, +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-case-insensitive.ts, 0, 21)) + + `Type 'Lowercase<${Print}>' is not assignable to 'Lowercase<${Print}>'`, +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-case-insensitive.ts, 0, 21)) + + `Type '${Print>}' is not assignable to '${Print>}'` +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-case-insensitive.ts, 0, 21)) + + ]> + : T +>T : Symbol(T, Decl(self-types-case-insensitive.ts, 0, 21)) + +declare const setHeader: +>setHeader : Symbol(setHeader, Decl(self-types-case-insensitive.ts, 11, 13)) + + (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void +>key : Symbol(key, Decl(self-types-case-insensitive.ts, 12, 3)) +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-case-insensitive.ts, 0, 0)) +>value : Symbol(value, Decl(self-types-case-insensitive.ts, 12, 49)) + +setHeader("Set-Cookie", "test") +>setHeader : Symbol(setHeader, Decl(self-types-case-insensitive.ts, 11, 13)) + +setHeader("Accept", "test2") +>setHeader : Symbol(setHeader, Decl(self-types-case-insensitive.ts, 11, 13)) + +setHeader("sEt-cOoKiE", "stop writing headers like this but ok") +>setHeader : Symbol(setHeader, Decl(self-types-case-insensitive.ts, 11, 13)) + +setHeader("Acept", "nah this has a typo") +>setHeader : Symbol(setHeader, Decl(self-types-case-insensitive.ts, 11, 13)) + +// TODO?: the autocompletion doesn't work, although it could be doable by +// instantiating `self` with `unknown`, at least in this case. +// Or by an alternative definition... +// type CaseInsensitive = T | [existing-defintion] +// the autocompletion works now but the custom error message doesn't +// get shown + +type Headers = +>Headers : Symbol(Headers, Decl(self-types-case-insensitive.ts, 17, 41)) + + Record, string> +>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --)) +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-case-insensitive.ts, 0, 0)) + +let headers: Headers = { +>headers : Symbol(headers, Decl(self-types-case-insensitive.ts, 29, 3)) +>Headers : Symbol(Headers, Decl(self-types-case-insensitive.ts, 17, 41)) + + // TODO: this is not an excess property, should compile + "Set-Cookie": "test" +>"Set-Cookie" : Symbol("Set-Cookie", Decl(self-types-case-insensitive.ts, 29, 24)) +} + +export {} diff --git a/tests/baselines/reference/self-types-case-insensitive.types b/tests/baselines/reference/self-types-case-insensitive.types new file mode 100644 index 0000000000000..1719596379ca3 --- /dev/null +++ b/tests/baselines/reference/self-types-case-insensitive.types @@ -0,0 +1,68 @@ +=== tests/cases/compiler/self-types-case-insensitive.ts === +type CaseInsensitive = +>CaseInsensitive : CaseInsensitive + + self extends string + ? Lowercase extends Lowercase + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'CaseInsensitive<${Print}>'`, + `Type 'Lowercase<${Print}>' is not assignable to 'Lowercase<${Print}>'`, + `Type '${Print>}' is not assignable to '${Print>}'` + ]> + : T + +declare const setHeader: +>setHeader : (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void + + (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void +>key : CaseInsensitive<"Set-Cookie" | "Accept"> +>value : string + +setHeader("Set-Cookie", "test") +>setHeader("Set-Cookie", "test") : void +>setHeader : (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void +>"Set-Cookie" : "Set-Cookie" +>"test" : "test" + +setHeader("Accept", "test2") +>setHeader("Accept", "test2") : void +>setHeader : (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void +>"Accept" : "Accept" +>"test2" : "test2" + +setHeader("sEt-cOoKiE", "stop writing headers like this but ok") +>setHeader("sEt-cOoKiE", "stop writing headers like this but ok") : void +>setHeader : (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void +>"sEt-cOoKiE" : "sEt-cOoKiE" +>"stop writing headers like this but ok" : "stop writing headers like this but ok" + +setHeader("Acept", "nah this has a typo") +>setHeader("Acept", "nah this has a typo") : void +>setHeader : (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void +>"Acept" : "Acept" +>"nah this has a typo" : "nah this has a typo" + +// TODO?: the autocompletion doesn't work, although it could be doable by +// instantiating `self` with `unknown`, at least in this case. +// Or by an alternative definition... +// type CaseInsensitive = T | [existing-defintion] +// the autocompletion works now but the custom error message doesn't +// get shown + +type Headers = +>Headers : { [P in CaseInsensitive<"set-cookie" | "accept">]: string; } + + Record, string> + +let headers: Headers = { +>headers : Headers +>{ // TODO: this is not an excess property, should compile "Set-Cookie": "test"} : { "Set-Cookie": string; } + + // TODO: this is not an excess property, should compile + "Set-Cookie": "test" +>"Set-Cookie" : string +>"test" : "test" +} + +export {} diff --git a/tests/baselines/reference/self-types-color.errors.txt b/tests/baselines/reference/self-types-color.errors.txt new file mode 100644 index 0000000000000..69398895a0d3f --- /dev/null +++ b/tests/baselines/reference/self-types-color.errors.txt @@ -0,0 +1,213 @@ +tests/cases/compiler/self-types-color.ts(10,7): error TS2322: Type 'number' is not assignable to type 'string'. +tests/cases/compiler/self-types-color.ts(11,7): error TS18051: Type 'string' is not assignable to type 'Color' + Expected a string literal +tests/cases/compiler/self-types-color.ts(13,7): error TS18051: Type '"#ffz"' is not assignable to type 'Color' + Expected an hexadecimal character got 'z' at column 3 +tests/cases/compiler/self-types-color.ts(14,7): error TS18051: Type '"rgb(100, 1000, 100)"' is not assignable to type 'Color' + Expected value from '0' to '255' got '1000' for green +tests/cases/compiler/self-types-color.ts(16,29): error TS18051: Type '"#ffz"' is not assignable to type 'Color' + Expected an hexadecimal character got 'z' at column 3 +tests/cases/compiler/self-types-color.ts(20,13): error TS2352: Conversion of type 'number' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. + + +==== tests/cases/compiler/self-types-color.ts (6 errors) ==== + type Color = + self extends string + ? ParseColor extends infer R + ? R extends { error: infer E extends string } + ? Never<[`Type '${Print}' is not assignable to type 'Color'`, E]> + : R + : never + : string + + const t0: Color = 123 + ~~ +!!! error TS2322: Type 'number' is not assignable to type 'string'. + const t1: Color = "hello" as string + ~~ +!!! error TS18051: Type 'string' is not assignable to type 'Color' +!!! error TS18051: Expected a string literal + const t2: Color = "#fff" + const t3: Color = "#ffz" + ~~ +!!! error TS18051: Type '"#ffz"' is not assignable to type 'Color' +!!! error TS18051: Expected an hexadecimal character got 'z' at column 3 + const t4: Color = "rgb(100, 1000, 100)" + ~~ +!!! error TS18051: Type '"rgb(100, 1000, 100)"' is not assignable to type 'Color' +!!! error TS18051: Expected value from '0' to '255' got '1000' for green + const t5 = "#fff" satisfies Color + const t6 = "#ffz" satisfies Color + ~~~~~ +!!! error TS18051: Type '"#ffz"' is not assignable to type 'Color' +!!! error TS18051: Expected an hexadecimal character got 'z' at column 3 + const t7 = "#fff" as Color + const t8 = "#ffz" as Color + const t9 = "this is fine" as Color + const t10 = 0 as Color + ~~~~~~~~~~ +!!! error TS2352: Conversion of type 'number' to type 'string' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first. + + + type ParseColor = + S.IsStringLiteral extends false ? { error: "Expected a string literal" } : + T extends NamedColor ? T : + T extends `#${string}` ? ParseHexColor : + T extends `rgb${string}` ? ParseRgbColor : + { error: "Expected it to start with '#' or 'rgb' or be a named color" } + + + type ParseHexColor> = + [I, C] extends [4, ""] | [7, ""] ? T : + I extends 0 | 1 | 2 | 3 | 4 | 5 | 6 + ? C extends (I extends 0 ? "#" : Hexadecimal) + ? ParseHexColor> + : { error: `Expected ${I extends 0 ? "#": "an hexadecimal character"} got '${S.Cast}' at column ${I}` } : + { error: `Unexpected character at ${N.Cast}` } + + + type Hexadecimal = + ( "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + | "a" | "b" | "c" | "d" | "e"| "f" + ) extends infer X + ? X | Uppercase> + : never + + type ParseRgbColor = + T extends `rgb${infer S}` + ? S extends `(${infer S}` + ? ParseNumberLessThanOrEqual, 255> extends infer X + ? X extends { error: infer E } ? { error: `${S.Cast} for red` } : + X extends { rest: infer S } ? + S.TrimedL extends `,${infer S}` + ? ParseNumberLessThanOrEqual, 255> extends infer X + ? X extends { error: infer E } ? { error: `${S.Cast} for green` } : + X extends { rest: infer S } ? + S.TrimedL extends `,${infer S}` + ? ParseNumberLessThanOrEqual, 255> extends infer X + ? X extends { error: infer E } ? { error: `${S.Cast} for blue` } : + X extends { rest: infer S } ? + S.TrimedR extends `)` + ? T + : { error: "Expected ')' after blue value at the end" } : + never + : never + : { error: "Expected ',' after green value" } : + never + : never + : { error: "Expected ',' after red value" } : + never + : never + : { error: `Expected '(' got ${S.Cast>} after rgb` } + : { error: `Expected 'rgb' at the start` } + + type ParseNumberLessThanOrEqual, V = N["value" & keyof N]> = + N extends { error: unknown } ? N : + Ns.IsLessThanOrEqual extends true ? N : + { error: `Expected value from '0' to '255' got '${S.Cast}'` } + + type ParseNumber> = + D extends { value: infer Nh, rest: infer Sh } + ? ParseNumber extends infer X + ? X extends { value: infer Nt, rest: infer S } + ? { value: `${S.Cast}${S.Cast}`, rest: S } + : { value: Nh, rest: Sh } + : never + : D + + type ParseDigit = + T extends `${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}${infer S}` + ? T extends `${infer V}${S}` + ? { value: `${V}`, rest: S } + : never + : { error: "Expected a number" } + + type NamedColor = + "black" | "silver" | "gray" | "white" | "maroon" | "red" | "purple" | "fuchsia" | "green" | "lime" | "olive" | "yellow" | "navy" | "blue" | "teal" | "aqua" | "aliceblue" | "antiquewhite" | "aqua" | "aquamarine" | "azure" | "beige" | "bisque" | "black" | "blanchedalmond" | "blue" | "blueviolet" | "brown" | "burlywood" | "cadetblue" | "chartreuse" | "chocolate" | "coral" | "cornflowerblue" | "cornsilk" | "crimson" | "cyan" | "darkblue" | "darkcyan" | "darkgoldenrod" | "darkgray" | "darkgreen" | "darkgrey" | "darkkhaki" | "darkmagenta" | "darkolivegreen" | "darkorange" | "darkorchid" | "darkred" | "darksalmon" | "darkseagreen" | "darkslateblue" | "darkslategray" | "darkslategrey" | "darkturquoise" | "darkviolet" | "deeppink" | "deepskyblue" | "dimgray" | "dimgrey" | "dodgerblue" | "firebrick" | "floralwhite" | "forestgreen" | "fuchsia" | "gainsboro" | "ghostwhite" | "gold" | "goldenrod" | "gray" | "green" | "greenyellow" | "grey" | "honeydew" | "hotpink" | "indianred" | "indigo" | "ivory" | "khaki" | "lavender" | "lavenderblush" | "lawngreen" | "lemonchiffon" | "lightblue" | "lightcoral" | "lightcyan" | "lightgoldenrodyellow" | "lightgray" | "lightgreen" | "lightgrey" | "lightpink" | "lightsalmon" | "lightseagreen" | "lightskyblue" | "lightslategray" | "lightslategrey" | "lightsteelblue" | "lightyellow" | "lime" | "limegreen" | "linen" | "magenta" | "maroon" | "mediumaquamarine" | "mediumblue" | "mediumorchid" | "mediumpurple" | "mediumseagreen" | "mediumslateblue" | "mediumspringgreen" | "mediumturquoise" | "mediumvioletred" | "midnightblue" | "mintcream" | "mistyrose" | "moccasin" | "navajowhite" | "navy" | "oldlace" | "olive" | "olivedrab" | "orange" | "orangered" | "orchid" | "palegoldenrod" | "palegreen" | "paleturquoise" | "palevioletred" | "papayawhip" | "peachpuff" | "peru" | "pink" | "plum" | "powderblue" | "purple" | "red" | "rosybrown" | "royalblue" | "saddlebrown" | "salmon" | "sandybrown" | "seagreen" | "seashell" | "sienna" | "silver" | "skyblue" | "slateblue" | "slategray" | "slategrey" | "snow" | "springgreen" | "steelblue" | "tan" | "teal" | "thistle" | "tomato" | "turquoise" | "violet" | "wheat" | "white" | "whitesmoke" | "yellow" | "yellowgreen" + + namespace S { + export type IsString = + T extends string ? true : false; + + export type IsStringLiteral = + IsString extends true + ? string extends T ? false : true + : false + + export type Cast = + A.Cast + + export type At = + Split extends { [_ in A.Cast]: infer X } + ? X + : "" + + export type Split = + T extends `${infer H}${infer T}` ? [H, ...Split] : + T extends "" ? [] : [T] + + export type TrimedL = + T extends ` ${infer T}` ? TrimedL : T + + export type TrimedR = + T extends `${infer T} ` ? TrimedL : T + + export type Length = + Split["length"] + + export type Shifted = + S extends `${infer _}${infer T}` ? T : never + } + + export namespace N { + export type Cast = A.Cast + + export type NaturalNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; + export type WholeNumbers = [0, ...NaturalNumbers]; + export type WholeNumbersUnshifted = [-1, ...WholeNumbers]; + + export type Increment = A.Get + export type Decrement = A.Get + } + + export namespace L { + export type SlicedH = + N extends 0 ? [] : + A extends [infer H, ...infer T] ? [H, ...SlicedH>] : + never + } + + export namespace Nd { + export type IsLessThanOrEqual = + A extends 0 ? true : + B extends A.Get>, number> ? false : + true + + export type IsLessThan = + A extends B ? false : + IsLessThanOrEqual + } + + export namespace Ns { + export type ToN = + { [N in keyof N.WholeNumbers]: + T extends N ? N.WholeNumbers[N] : never + }[keyof N.WholeNumbers] + + export type TrimL = + T extends `0${infer T}` ? TrimL : T + + export type IsLessThanOrEqual<_A, _B, A = TrimL<_A>, B = TrimL<_B>> = + Nd.IsLessThan, S.Length> extends true ? true : + S.Length extends S.Length + ? Nd.IsLessThan>, ToN>> extends true ? true : + S.At extends S.At ? IsLessThanOrEqual, S.Shifted> : + false : + false + } + + + export namespace A { + export type Cast = T extends U ? T : U; + export type Get = K extends keyof T ? T[K] : never + } \ No newline at end of file diff --git a/tests/baselines/reference/self-types-color.js b/tests/baselines/reference/self-types-color.js new file mode 100644 index 0000000000000..ef6ebf949a51a --- /dev/null +++ b/tests/baselines/reference/self-types-color.js @@ -0,0 +1,200 @@ +//// [self-types-color.ts] +type Color = + self extends string + ? ParseColor extends infer R + ? R extends { error: infer E extends string } + ? Never<[`Type '${Print}' is not assignable to type 'Color'`, E]> + : R + : never + : string + +const t0: Color = 123 +const t1: Color = "hello" as string +const t2: Color = "#fff" +const t3: Color = "#ffz" +const t4: Color = "rgb(100, 1000, 100)" +const t5 = "#fff" satisfies Color +const t6 = "#ffz" satisfies Color +const t7 = "#fff" as Color +const t8 = "#ffz" as Color +const t9 = "this is fine" as Color +const t10 = 0 as Color + + +type ParseColor = + S.IsStringLiteral extends false ? { error: "Expected a string literal" } : + T extends NamedColor ? T : + T extends `#${string}` ? ParseHexColor : + T extends `rgb${string}` ? ParseRgbColor : + { error: "Expected it to start with '#' or 'rgb' or be a named color" } + + +type ParseHexColor> = + [I, C] extends [4, ""] | [7, ""] ? T : + I extends 0 | 1 | 2 | 3 | 4 | 5 | 6 + ? C extends (I extends 0 ? "#" : Hexadecimal) + ? ParseHexColor> + : { error: `Expected ${I extends 0 ? "#": "an hexadecimal character"} got '${S.Cast}' at column ${I}` } : + { error: `Unexpected character at ${N.Cast}` } + + +type Hexadecimal = + ( "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + | "a" | "b" | "c" | "d" | "e"| "f" + ) extends infer X + ? X | Uppercase> + : never + +type ParseRgbColor = + T extends `rgb${infer S}` + ? S extends `(${infer S}` + ? ParseNumberLessThanOrEqual, 255> extends infer X + ? X extends { error: infer E } ? { error: `${S.Cast} for red` } : + X extends { rest: infer S } ? + S.TrimedL extends `,${infer S}` + ? ParseNumberLessThanOrEqual, 255> extends infer X + ? X extends { error: infer E } ? { error: `${S.Cast} for green` } : + X extends { rest: infer S } ? + S.TrimedL extends `,${infer S}` + ? ParseNumberLessThanOrEqual, 255> extends infer X + ? X extends { error: infer E } ? { error: `${S.Cast} for blue` } : + X extends { rest: infer S } ? + S.TrimedR extends `)` + ? T + : { error: "Expected ')' after blue value at the end" } : + never + : never + : { error: "Expected ',' after green value" } : + never + : never + : { error: "Expected ',' after red value" } : + never + : never + : { error: `Expected '(' got ${S.Cast>} after rgb` } + : { error: `Expected 'rgb' at the start` } + +type ParseNumberLessThanOrEqual, V = N["value" & keyof N]> = + N extends { error: unknown } ? N : + Ns.IsLessThanOrEqual extends true ? N : + { error: `Expected value from '0' to '255' got '${S.Cast}'` } + +type ParseNumber> = + D extends { value: infer Nh, rest: infer Sh } + ? ParseNumber extends infer X + ? X extends { value: infer Nt, rest: infer S } + ? { value: `${S.Cast}${S.Cast}`, rest: S } + : { value: Nh, rest: Sh } + : never + : D + +type ParseDigit = + T extends `${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}${infer S}` + ? T extends `${infer V}${S}` + ? { value: `${V}`, rest: S } + : never + : { error: "Expected a number" } + +type NamedColor = + "black" | "silver" | "gray" | "white" | "maroon" | "red" | "purple" | "fuchsia" | "green" | "lime" | "olive" | "yellow" | "navy" | "blue" | "teal" | "aqua" | "aliceblue" | "antiquewhite" | "aqua" | "aquamarine" | "azure" | "beige" | "bisque" | "black" | "blanchedalmond" | "blue" | "blueviolet" | "brown" | "burlywood" | "cadetblue" | "chartreuse" | "chocolate" | "coral" | "cornflowerblue" | "cornsilk" | "crimson" | "cyan" | "darkblue" | "darkcyan" | "darkgoldenrod" | "darkgray" | "darkgreen" | "darkgrey" | "darkkhaki" | "darkmagenta" | "darkolivegreen" | "darkorange" | "darkorchid" | "darkred" | "darksalmon" | "darkseagreen" | "darkslateblue" | "darkslategray" | "darkslategrey" | "darkturquoise" | "darkviolet" | "deeppink" | "deepskyblue" | "dimgray" | "dimgrey" | "dodgerblue" | "firebrick" | "floralwhite" | "forestgreen" | "fuchsia" | "gainsboro" | "ghostwhite" | "gold" | "goldenrod" | "gray" | "green" | "greenyellow" | "grey" | "honeydew" | "hotpink" | "indianred" | "indigo" | "ivory" | "khaki" | "lavender" | "lavenderblush" | "lawngreen" | "lemonchiffon" | "lightblue" | "lightcoral" | "lightcyan" | "lightgoldenrodyellow" | "lightgray" | "lightgreen" | "lightgrey" | "lightpink" | "lightsalmon" | "lightseagreen" | "lightskyblue" | "lightslategray" | "lightslategrey" | "lightsteelblue" | "lightyellow" | "lime" | "limegreen" | "linen" | "magenta" | "maroon" | "mediumaquamarine" | "mediumblue" | "mediumorchid" | "mediumpurple" | "mediumseagreen" | "mediumslateblue" | "mediumspringgreen" | "mediumturquoise" | "mediumvioletred" | "midnightblue" | "mintcream" | "mistyrose" | "moccasin" | "navajowhite" | "navy" | "oldlace" | "olive" | "olivedrab" | "orange" | "orangered" | "orchid" | "palegoldenrod" | "palegreen" | "paleturquoise" | "palevioletred" | "papayawhip" | "peachpuff" | "peru" | "pink" | "plum" | "powderblue" | "purple" | "red" | "rosybrown" | "royalblue" | "saddlebrown" | "salmon" | "sandybrown" | "seagreen" | "seashell" | "sienna" | "silver" | "skyblue" | "slateblue" | "slategray" | "slategrey" | "snow" | "springgreen" | "steelblue" | "tan" | "teal" | "thistle" | "tomato" | "turquoise" | "violet" | "wheat" | "white" | "whitesmoke" | "yellow" | "yellowgreen" + +namespace S { + export type IsString = + T extends string ? true : false; + + export type IsStringLiteral = + IsString extends true + ? string extends T ? false : true + : false + + export type Cast = + A.Cast + + export type At = + Split extends { [_ in A.Cast]: infer X } + ? X + : "" + + export type Split = + T extends `${infer H}${infer T}` ? [H, ...Split] : + T extends "" ? [] : [T] + + export type TrimedL = + T extends ` ${infer T}` ? TrimedL : T + + export type TrimedR = + T extends `${infer T} ` ? TrimedL : T + + export type Length = + Split["length"] + + export type Shifted = + S extends `${infer _}${infer T}` ? T : never +} + +export namespace N { + export type Cast = A.Cast + + export type NaturalNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; + export type WholeNumbers = [0, ...NaturalNumbers]; + export type WholeNumbersUnshifted = [-1, ...WholeNumbers]; + + export type Increment = A.Get + export type Decrement = A.Get +} + +export namespace L { + export type SlicedH = + N extends 0 ? [] : + A extends [infer H, ...infer T] ? [H, ...SlicedH>] : + never +} + +export namespace Nd { + export type IsLessThanOrEqual = + A extends 0 ? true : + B extends A.Get>, number> ? false : + true + + export type IsLessThan = + A extends B ? false : + IsLessThanOrEqual +} + +export namespace Ns { + export type ToN = + { [N in keyof N.WholeNumbers]: + T extends N ? N.WholeNumbers[N] : never + }[keyof N.WholeNumbers] + + export type TrimL = + T extends `0${infer T}` ? TrimL : T + + export type IsLessThanOrEqual<_A, _B, A = TrimL<_A>, B = TrimL<_B>> = + Nd.IsLessThan, S.Length> extends true ? true : + S.Length extends S.Length + ? Nd.IsLessThan>, ToN>> extends true ? true : + S.At extends S.At ? IsLessThanOrEqual, S.Shifted> : + false : + false +} + + +export namespace A { + export type Cast = T extends U ? T : U; + export type Get = K extends keyof T ? T[K] : never +} + +//// [self-types-color.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var t0 = 123; +var t1 = "hello"; +var t2 = "#fff"; +var t3 = "#ffz"; +var t4 = "rgb(100, 1000, 100)"; +var t5 = "#fff"; +var t6 = "#ffz"; +var t7 = "#fff"; +var t8 = "#ffz"; +var t9 = "this is fine"; +var t10 = 0; diff --git a/tests/baselines/reference/self-types-color.symbols b/tests/baselines/reference/self-types-color.symbols new file mode 100644 index 0000000000000..23b2204a2a165 --- /dev/null +++ b/tests/baselines/reference/self-types-color.symbols @@ -0,0 +1,713 @@ +=== tests/cases/compiler/self-types-color.ts === +type Color = +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + + self extends string + ? ParseColor extends infer R +>ParseColor : Symbol(ParseColor, Decl(self-types-color.ts, 19, 22)) +>R : Symbol(R, Decl(self-types-color.ts, 2, 36)) + + ? R extends { error: infer E extends string } +>R : Symbol(R, Decl(self-types-color.ts, 2, 36)) +>error : Symbol(error, Decl(self-types-color.ts, 3, 19)) +>E : Symbol(E, Decl(self-types-color.ts, 3, 32)) + + ? Never<[`Type '${Print}' is not assignable to type 'Color'`, E]> +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>E : Symbol(E, Decl(self-types-color.ts, 3, 32)) + + : R +>R : Symbol(R, Decl(self-types-color.ts, 2, 36)) + + : never + : string + +const t0: Color = 123 +>t0 : Symbol(t0, Decl(self-types-color.ts, 9, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + +const t1: Color = "hello" as string +>t1 : Symbol(t1, Decl(self-types-color.ts, 10, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + +const t2: Color = "#fff" +>t2 : Symbol(t2, Decl(self-types-color.ts, 11, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + +const t3: Color = "#ffz" +>t3 : Symbol(t3, Decl(self-types-color.ts, 12, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + +const t4: Color = "rgb(100, 1000, 100)" +>t4 : Symbol(t4, Decl(self-types-color.ts, 13, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + +const t5 = "#fff" satisfies Color +>t5 : Symbol(t5, Decl(self-types-color.ts, 14, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + +const t6 = "#ffz" satisfies Color +>t6 : Symbol(t6, Decl(self-types-color.ts, 15, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + +const t7 = "#fff" as Color +>t7 : Symbol(t7, Decl(self-types-color.ts, 16, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + +const t8 = "#ffz" as Color +>t8 : Symbol(t8, Decl(self-types-color.ts, 17, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + +const t9 = "this is fine" as Color +>t9 : Symbol(t9, Decl(self-types-color.ts, 18, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + +const t10 = 0 as Color +>t10 : Symbol(t10, Decl(self-types-color.ts, 19, 5)) +>Color : Symbol(Color, Decl(self-types-color.ts, 0, 0)) + + +type ParseColor = +>ParseColor : Symbol(ParseColor, Decl(self-types-color.ts, 19, 22)) +>T : Symbol(T, Decl(self-types-color.ts, 22, 16)) + + S.IsStringLiteral extends false ? { error: "Expected a string literal" } : +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>IsStringLiteral : Symbol(S.IsStringLiteral, Decl(self-types-color.ts, 100, 36)) +>T : Symbol(T, Decl(self-types-color.ts, 22, 16)) +>error : Symbol(error, Decl(self-types-color.ts, 23, 40)) + + T extends NamedColor ? T : +>T : Symbol(T, Decl(self-types-color.ts, 22, 16)) +>NamedColor : Symbol(NamedColor, Decl(self-types-color.ts, 93, 36)) +>T : Symbol(T, Decl(self-types-color.ts, 22, 16)) + + T extends `#${string}` ? ParseHexColor : +>T : Symbol(T, Decl(self-types-color.ts, 22, 16)) +>ParseHexColor : Symbol(ParseHexColor, Decl(self-types-color.ts, 27, 73)) +>T : Symbol(T, Decl(self-types-color.ts, 22, 16)) + + T extends `rgb${string}` ? ParseRgbColor : +>T : Symbol(T, Decl(self-types-color.ts, 22, 16)) +>ParseRgbColor : Symbol(ParseRgbColor, Decl(self-types-color.ts, 44, 11)) +>T : Symbol(T, Decl(self-types-color.ts, 22, 16)) + + { error: "Expected it to start with '#' or 'rgb' or be a named color" } +>error : Symbol(error, Decl(self-types-color.ts, 27, 3)) + + +type ParseHexColor> = +>ParseHexColor : Symbol(ParseHexColor, Decl(self-types-color.ts, 27, 73)) +>T : Symbol(T, Decl(self-types-color.ts, 30, 19)) +>I : Symbol(I, Decl(self-types-color.ts, 30, 21)) +>C : Symbol(C, Decl(self-types-color.ts, 30, 28)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>At : Symbol(S.At, Decl(self-types-color.ts, 108, 21)) +>T : Symbol(T, Decl(self-types-color.ts, 30, 19)) +>I : Symbol(I, Decl(self-types-color.ts, 30, 21)) + + [I, C] extends [4, ""] | [7, ""] ? T : +>I : Symbol(I, Decl(self-types-color.ts, 30, 21)) +>C : Symbol(C, Decl(self-types-color.ts, 30, 28)) +>T : Symbol(T, Decl(self-types-color.ts, 30, 19)) + + I extends 0 | 1 | 2 | 3 | 4 | 5 | 6 +>I : Symbol(I, Decl(self-types-color.ts, 30, 21)) + + ? C extends (I extends 0 ? "#" : Hexadecimal) +>C : Symbol(C, Decl(self-types-color.ts, 30, 28)) +>I : Symbol(I, Decl(self-types-color.ts, 30, 21)) +>Hexadecimal : Symbol(Hexadecimal, Decl(self-types-color.ts, 36, 51)) + + ? ParseHexColor> +>ParseHexColor : Symbol(ParseHexColor, Decl(self-types-color.ts, 27, 73)) +>T : Symbol(T, Decl(self-types-color.ts, 30, 19)) +>N : Symbol(N, Decl(self-types-color.ts, 130, 1)) +>Increment : Symbol(N.Increment, Decl(self-types-color.ts, 137, 60)) +>I : Symbol(I, Decl(self-types-color.ts, 30, 21)) + + : { error: `Expected ${I extends 0 ? "#": "an hexadecimal character"} got '${S.Cast}' at column ${I}` } : +>error : Symbol(error, Decl(self-types-color.ts, 35, 9)) +>I : Symbol(I, Decl(self-types-color.ts, 30, 21)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Cast : Symbol(S.Cast, Decl(self-types-color.ts, 105, 13)) +>C : Symbol(C, Decl(self-types-color.ts, 30, 28)) +>I : Symbol(I, Decl(self-types-color.ts, 30, 21)) + + { error: `Unexpected character at ${N.Cast}` } +>error : Symbol(error, Decl(self-types-color.ts, 36, 3)) +>N : Symbol(N, Decl(self-types-color.ts, 130, 1)) +>Cast : Symbol(N.Cast, Decl(self-types-color.ts, 132, 20)) +>I : Symbol(I, Decl(self-types-color.ts, 30, 21)) + + +type Hexadecimal = +>Hexadecimal : Symbol(Hexadecimal, Decl(self-types-color.ts, 36, 51)) + + ( "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + | "a" | "b" | "c" | "d" | "e"| "f" + ) extends infer X +>X : Symbol(X, Decl(self-types-color.ts, 42, 17)) + + ? X | Uppercase> +>X : Symbol(X, Decl(self-types-color.ts, 42, 17)) +>Uppercase : Symbol(Uppercase, Decl(lib.es5.d.ts, --, --)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Cast : Symbol(S.Cast, Decl(self-types-color.ts, 105, 13)) +>X : Symbol(X, Decl(self-types-color.ts, 42, 17)) + + : never + +type ParseRgbColor = +>ParseRgbColor : Symbol(ParseRgbColor, Decl(self-types-color.ts, 44, 11)) +>T : Symbol(T, Decl(self-types-color.ts, 46, 19)) + + T extends `rgb${infer S}` +>T : Symbol(T, Decl(self-types-color.ts, 46, 19)) +>S : Symbol(S, Decl(self-types-color.ts, 47, 23)) + + ? S extends `(${infer S}` +>S : Symbol(S, Decl(self-types-color.ts, 47, 23)) +>S : Symbol(S, Decl(self-types-color.ts, 48, 25)) + + ? ParseNumberLessThanOrEqual, 255> extends infer X +>ParseNumberLessThanOrEqual : Symbol(ParseNumberLessThanOrEqual, Decl(self-types-color.ts, 72, 46)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>TrimedL : Symbol(S.TrimedL, Decl(self-types-color.ts, 117, 27)) +>S : Symbol(S, Decl(self-types-color.ts, 48, 25)) +>X : Symbol(X, Decl(self-types-color.ts, 49, 69)) + + ? X extends { error: infer E } ? { error: `${S.Cast} for red` } : +>X : Symbol(X, Decl(self-types-color.ts, 49, 69)) +>error : Symbol(error, Decl(self-types-color.ts, 50, 25)) +>E : Symbol(E, Decl(self-types-color.ts, 50, 38)) +>error : Symbol(error, Decl(self-types-color.ts, 50, 46)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Cast : Symbol(S.Cast, Decl(self-types-color.ts, 105, 13)) +>E : Symbol(E, Decl(self-types-color.ts, 50, 38)) + + X extends { rest: infer S } ? +>X : Symbol(X, Decl(self-types-color.ts, 49, 69)) +>rest : Symbol(rest, Decl(self-types-color.ts, 51, 25)) +>S : Symbol(S, Decl(self-types-color.ts, 51, 37)) + + S.TrimedL extends `,${infer S}` +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>TrimedL : Symbol(S.TrimedL, Decl(self-types-color.ts, 117, 27)) +>S : Symbol(S, Decl(self-types-color.ts, 51, 37)) +>S : Symbol(S, Decl(self-types-color.ts, 52, 46)) + + ? ParseNumberLessThanOrEqual, 255> extends infer X +>ParseNumberLessThanOrEqual : Symbol(ParseNumberLessThanOrEqual, Decl(self-types-color.ts, 72, 46)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>TrimedL : Symbol(S.TrimedL, Decl(self-types-color.ts, 117, 27)) +>S : Symbol(S, Decl(self-types-color.ts, 52, 46)) +>X : Symbol(X, Decl(self-types-color.ts, 53, 79)) + + ? X extends { error: infer E } ? { error: `${S.Cast} for green` } : +>X : Symbol(X, Decl(self-types-color.ts, 53, 79)) +>error : Symbol(error, Decl(self-types-color.ts, 54, 35)) +>E : Symbol(E, Decl(self-types-color.ts, 54, 48)) +>error : Symbol(error, Decl(self-types-color.ts, 54, 56)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Cast : Symbol(S.Cast, Decl(self-types-color.ts, 105, 13)) +>E : Symbol(E, Decl(self-types-color.ts, 54, 48)) + + X extends { rest: infer S } ? +>X : Symbol(X, Decl(self-types-color.ts, 53, 79)) +>rest : Symbol(rest, Decl(self-types-color.ts, 55, 35)) +>S : Symbol(S, Decl(self-types-color.ts, 55, 47)) + + S.TrimedL extends `,${infer S}` +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>TrimedL : Symbol(S.TrimedL, Decl(self-types-color.ts, 117, 27)) +>S : Symbol(S, Decl(self-types-color.ts, 55, 47)) +>S : Symbol(S, Decl(self-types-color.ts, 56, 56)) + + ? ParseNumberLessThanOrEqual, 255> extends infer X +>ParseNumberLessThanOrEqual : Symbol(ParseNumberLessThanOrEqual, Decl(self-types-color.ts, 72, 46)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>TrimedL : Symbol(S.TrimedL, Decl(self-types-color.ts, 117, 27)) +>S : Symbol(S, Decl(self-types-color.ts, 56, 56)) +>X : Symbol(X, Decl(self-types-color.ts, 57, 89)) + + ? X extends { error: infer E } ? { error: `${S.Cast} for blue` } : +>X : Symbol(X, Decl(self-types-color.ts, 57, 89)) +>error : Symbol(error, Decl(self-types-color.ts, 58, 45)) +>E : Symbol(E, Decl(self-types-color.ts, 58, 58)) +>error : Symbol(error, Decl(self-types-color.ts, 58, 66)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Cast : Symbol(S.Cast, Decl(self-types-color.ts, 105, 13)) +>E : Symbol(E, Decl(self-types-color.ts, 58, 58)) + + X extends { rest: infer S } ? +>X : Symbol(X, Decl(self-types-color.ts, 57, 89)) +>rest : Symbol(rest, Decl(self-types-color.ts, 59, 45)) +>S : Symbol(S, Decl(self-types-color.ts, 59, 57)) + + S.TrimedR extends `)` +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>TrimedR : Symbol(S.TrimedR, Decl(self-types-color.ts, 120, 44)) +>S : Symbol(S, Decl(self-types-color.ts, 59, 57)) + + ? T +>T : Symbol(T, Decl(self-types-color.ts, 46, 19)) + + : { error: "Expected ')' after blue value at the end" } : +>error : Symbol(error, Decl(self-types-color.ts, 62, 41)) + + never + : never + : { error: "Expected ',' after green value" } : +>error : Symbol(error, Decl(self-types-color.ts, 65, 31)) + + never + : never + : { error: "Expected ',' after red value" } : +>error : Symbol(error, Decl(self-types-color.ts, 68, 21)) + + never + : never + : { error: `Expected '(' got ${S.Cast>} after rgb` } +>error : Symbol(error, Decl(self-types-color.ts, 71, 11)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Cast : Symbol(S.Cast, Decl(self-types-color.ts, 105, 13)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>At : Symbol(S.At, Decl(self-types-color.ts, 108, 21)) +>T : Symbol(T, Decl(self-types-color.ts, 46, 19)) + + : { error: `Expected 'rgb' at the start` } +>error : Symbol(error, Decl(self-types-color.ts, 72, 7)) + +type ParseNumberLessThanOrEqual, V = N["value" & keyof N]> = +>ParseNumberLessThanOrEqual : Symbol(ParseNumberLessThanOrEqual, Decl(self-types-color.ts, 72, 46)) +>T : Symbol(T, Decl(self-types-color.ts, 74, 32)) +>M : Symbol(M, Decl(self-types-color.ts, 74, 34)) +>N : Symbol(N, Decl(self-types-color.ts, 74, 52)) +>ParseNumber : Symbol(ParseNumber, Decl(self-types-color.ts, 77, 66)) +>T : Symbol(T, Decl(self-types-color.ts, 74, 32)) +>V : Symbol(V, Decl(self-types-color.ts, 74, 72)) +>N : Symbol(N, Decl(self-types-color.ts, 74, 52)) +>N : Symbol(N, Decl(self-types-color.ts, 74, 52)) + + N extends { error: unknown } ? N : +>N : Symbol(N, Decl(self-types-color.ts, 74, 52)) +>error : Symbol(error, Decl(self-types-color.ts, 75, 13)) +>N : Symbol(N, Decl(self-types-color.ts, 74, 52)) + + Ns.IsLessThanOrEqual extends true ? N : +>Ns : Symbol(Ns, Decl(self-types-color.ts, 159, 1)) +>IsLessThanOrEqual : Symbol(Ns.IsLessThanOrEqual, Decl(self-types-color.ts, 168, 42)) +>V : Symbol(V, Decl(self-types-color.ts, 74, 72)) +>M : Symbol(M, Decl(self-types-color.ts, 74, 34)) +>N : Symbol(N, Decl(self-types-color.ts, 74, 52)) + + { error: `Expected value from '0' to '255' got '${S.Cast}'` } +>error : Symbol(error, Decl(self-types-color.ts, 77, 3)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Cast : Symbol(S.Cast, Decl(self-types-color.ts, 105, 13)) +>V : Symbol(V, Decl(self-types-color.ts, 74, 72)) + +type ParseNumber> = +>ParseNumber : Symbol(ParseNumber, Decl(self-types-color.ts, 77, 66)) +>T : Symbol(T, Decl(self-types-color.ts, 79, 17)) +>D : Symbol(D, Decl(self-types-color.ts, 79, 19)) +>ParseDigit : Symbol(ParseDigit, Decl(self-types-color.ts, 86, 7)) +>T : Symbol(T, Decl(self-types-color.ts, 79, 17)) + + D extends { value: infer Nh, rest: infer Sh } +>D : Symbol(D, Decl(self-types-color.ts, 79, 19)) +>value : Symbol(value, Decl(self-types-color.ts, 80, 14)) +>Nh : Symbol(Nh, Decl(self-types-color.ts, 80, 27)) +>rest : Symbol(rest, Decl(self-types-color.ts, 80, 31)) +>Sh : Symbol(Sh, Decl(self-types-color.ts, 80, 43)) + + ? ParseNumber extends infer X +>ParseNumber : Symbol(ParseNumber, Decl(self-types-color.ts, 77, 66)) +>Sh : Symbol(Sh, Decl(self-types-color.ts, 80, 43)) +>X : Symbol(X, Decl(self-types-color.ts, 81, 35)) + + ? X extends { value: infer Nt, rest: infer S } +>X : Symbol(X, Decl(self-types-color.ts, 81, 35)) +>value : Symbol(value, Decl(self-types-color.ts, 82, 21)) +>Nt : Symbol(Nt, Decl(self-types-color.ts, 82, 34)) +>rest : Symbol(rest, Decl(self-types-color.ts, 82, 38)) +>S : Symbol(S, Decl(self-types-color.ts, 82, 50)) + + ? { value: `${S.Cast}${S.Cast}`, rest: S } +>value : Symbol(value, Decl(self-types-color.ts, 83, 15)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Cast : Symbol(S.Cast, Decl(self-types-color.ts, 105, 13)) +>Nh : Symbol(Nh, Decl(self-types-color.ts, 80, 27)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Cast : Symbol(S.Cast, Decl(self-types-color.ts, 105, 13)) +>Nt : Symbol(Nt, Decl(self-types-color.ts, 82, 34)) +>rest : Symbol(rest, Decl(self-types-color.ts, 83, 52)) +>S : Symbol(S, Decl(self-types-color.ts, 82, 50)) + + : { value: Nh, rest: Sh } +>value : Symbol(value, Decl(self-types-color.ts, 84, 15)) +>Nh : Symbol(Nh, Decl(self-types-color.ts, 80, 27)) +>rest : Symbol(rest, Decl(self-types-color.ts, 84, 26)) +>Sh : Symbol(Sh, Decl(self-types-color.ts, 80, 43)) + + : never + : D +>D : Symbol(D, Decl(self-types-color.ts, 79, 19)) + +type ParseDigit = +>ParseDigit : Symbol(ParseDigit, Decl(self-types-color.ts, 86, 7)) +>T : Symbol(T, Decl(self-types-color.ts, 88, 16)) + + T extends `${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}${infer S}` +>T : Symbol(T, Decl(self-types-color.ts, 88, 16)) +>S : Symbol(S, Decl(self-types-color.ts, 89, 60)) + + ? T extends `${infer V}${S}` +>T : Symbol(T, Decl(self-types-color.ts, 88, 16)) +>V : Symbol(V, Decl(self-types-color.ts, 90, 24)) +>S : Symbol(S, Decl(self-types-color.ts, 89, 60)) + + ? { value: `${V}`, rest: S } +>value : Symbol(value, Decl(self-types-color.ts, 91, 11)) +>V : Symbol(V, Decl(self-types-color.ts, 90, 24)) +>rest : Symbol(rest, Decl(self-types-color.ts, 91, 26)) +>S : Symbol(S, Decl(self-types-color.ts, 89, 60)) + + : never + : { error: "Expected a number" } +>error : Symbol(error, Decl(self-types-color.ts, 93, 7)) + +type NamedColor = +>NamedColor : Symbol(NamedColor, Decl(self-types-color.ts, 93, 36)) + + "black" | "silver" | "gray" | "white" | "maroon" | "red" | "purple" | "fuchsia" | "green" | "lime" | "olive" | "yellow" | "navy" | "blue" | "teal" | "aqua" | "aliceblue" | "antiquewhite" | "aqua" | "aquamarine" | "azure" | "beige" | "bisque" | "black" | "blanchedalmond" | "blue" | "blueviolet" | "brown" | "burlywood" | "cadetblue" | "chartreuse" | "chocolate" | "coral" | "cornflowerblue" | "cornsilk" | "crimson" | "cyan" | "darkblue" | "darkcyan" | "darkgoldenrod" | "darkgray" | "darkgreen" | "darkgrey" | "darkkhaki" | "darkmagenta" | "darkolivegreen" | "darkorange" | "darkorchid" | "darkred" | "darksalmon" | "darkseagreen" | "darkslateblue" | "darkslategray" | "darkslategrey" | "darkturquoise" | "darkviolet" | "deeppink" | "deepskyblue" | "dimgray" | "dimgrey" | "dodgerblue" | "firebrick" | "floralwhite" | "forestgreen" | "fuchsia" | "gainsboro" | "ghostwhite" | "gold" | "goldenrod" | "gray" | "green" | "greenyellow" | "grey" | "honeydew" | "hotpink" | "indianred" | "indigo" | "ivory" | "khaki" | "lavender" | "lavenderblush" | "lawngreen" | "lemonchiffon" | "lightblue" | "lightcoral" | "lightcyan" | "lightgoldenrodyellow" | "lightgray" | "lightgreen" | "lightgrey" | "lightpink" | "lightsalmon" | "lightseagreen" | "lightskyblue" | "lightslategray" | "lightslategrey" | "lightsteelblue" | "lightyellow" | "lime" | "limegreen" | "linen" | "magenta" | "maroon" | "mediumaquamarine" | "mediumblue" | "mediumorchid" | "mediumpurple" | "mediumseagreen" | "mediumslateblue" | "mediumspringgreen" | "mediumturquoise" | "mediumvioletred" | "midnightblue" | "mintcream" | "mistyrose" | "moccasin" | "navajowhite" | "navy" | "oldlace" | "olive" | "olivedrab" | "orange" | "orangered" | "orchid" | "palegoldenrod" | "palegreen" | "paleturquoise" | "palevioletred" | "papayawhip" | "peachpuff" | "peru" | "pink" | "plum" | "powderblue" | "purple" | "red" | "rosybrown" | "royalblue" | "saddlebrown" | "salmon" | "sandybrown" | "seagreen" | "seashell" | "sienna" | "silver" | "skyblue" | "slateblue" | "slategray" | "slategrey" | "snow" | "springgreen" | "steelblue" | "tan" | "teal" | "thistle" | "tomato" | "turquoise" | "violet" | "wheat" | "white" | "whitesmoke" | "yellow" | "yellowgreen" + +namespace S { +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) + + export type IsString = +>IsString : Symbol(IsString, Decl(self-types-color.ts, 98, 13)) +>T : Symbol(T, Decl(self-types-color.ts, 99, 23)) + + T extends string ? true : false; +>T : Symbol(T, Decl(self-types-color.ts, 99, 23)) + + export type IsStringLiteral = +>IsStringLiteral : Symbol(IsStringLiteral, Decl(self-types-color.ts, 100, 36)) +>T : Symbol(T, Decl(self-types-color.ts, 102, 30)) + + IsString extends true +>IsString : Symbol(IsString, Decl(self-types-color.ts, 98, 13)) +>T : Symbol(T, Decl(self-types-color.ts, 102, 30)) + + ? string extends T ? false : true +>T : Symbol(T, Decl(self-types-color.ts, 102, 30)) + + : false + + export type Cast = +>Cast : Symbol(Cast, Decl(self-types-color.ts, 105, 13)) +>T : Symbol(T, Decl(self-types-color.ts, 107, 19)) + + A.Cast +>A : Symbol(A, Decl(self-types-color.ts, 177, 1)) +>Cast : Symbol(A.Cast, Decl(self-types-color.ts, 180, 20)) +>T : Symbol(T, Decl(self-types-color.ts, 107, 19)) + + export type At = +>At : Symbol(At, Decl(self-types-color.ts, 108, 21)) +>S : Symbol(S, Decl(self-types-color.ts, 110, 17)) +>I : Symbol(I, Decl(self-types-color.ts, 110, 19)) + + Split extends { [_ in A.Cast]: infer X } +>Split : Symbol(Split, Decl(self-types-color.ts, 113, 10)) +>S : Symbol(S, Decl(self-types-color.ts, 110, 17)) +>_ : Symbol(_, Decl(self-types-color.ts, 111, 24)) +>A : Symbol(A, Decl(self-types-color.ts, 177, 1)) +>Cast : Symbol(A.Cast, Decl(self-types-color.ts, 180, 20)) +>I : Symbol(I, Decl(self-types-color.ts, 110, 19)) +>X : Symbol(X, Decl(self-types-color.ts, 111, 54)) + + ? X +>X : Symbol(X, Decl(self-types-color.ts, 111, 54)) + + : "" + + export type Split = +>Split : Symbol(Split, Decl(self-types-color.ts, 113, 10)) +>T : Symbol(T, Decl(self-types-color.ts, 115, 20)) + + T extends `${infer H}${infer T}` ? [H, ...Split] : +>T : Symbol(T, Decl(self-types-color.ts, 115, 20)) +>H : Symbol(H, Decl(self-types-color.ts, 116, 22)) +>T : Symbol(T, Decl(self-types-color.ts, 116, 32)) +>H : Symbol(H, Decl(self-types-color.ts, 116, 22)) +>Split : Symbol(Split, Decl(self-types-color.ts, 113, 10)) +>T : Symbol(T, Decl(self-types-color.ts, 116, 32)) + + T extends "" ? [] : [T] +>T : Symbol(T, Decl(self-types-color.ts, 115, 20)) +>T : Symbol(T, Decl(self-types-color.ts, 115, 20)) + + export type TrimedL = +>TrimedL : Symbol(TrimedL, Decl(self-types-color.ts, 117, 27)) +>T : Symbol(T, Decl(self-types-color.ts, 119, 22)) + + T extends ` ${infer T}` ? TrimedL : T +>T : Symbol(T, Decl(self-types-color.ts, 119, 22)) +>T : Symbol(T, Decl(self-types-color.ts, 120, 23)) +>TrimedL : Symbol(TrimedL, Decl(self-types-color.ts, 117, 27)) +>T : Symbol(T, Decl(self-types-color.ts, 120, 23)) +>T : Symbol(T, Decl(self-types-color.ts, 119, 22)) + + export type TrimedR = +>TrimedR : Symbol(TrimedR, Decl(self-types-color.ts, 120, 44)) +>T : Symbol(T, Decl(self-types-color.ts, 122, 22)) + + T extends `${infer T} ` ? TrimedL : T +>T : Symbol(T, Decl(self-types-color.ts, 122, 22)) +>T : Symbol(T, Decl(self-types-color.ts, 123, 22)) +>TrimedL : Symbol(TrimedL, Decl(self-types-color.ts, 117, 27)) +>T : Symbol(T, Decl(self-types-color.ts, 123, 22)) +>T : Symbol(T, Decl(self-types-color.ts, 122, 22)) + + export type Length = +>Length : Symbol(Length, Decl(self-types-color.ts, 123, 44)) +>S : Symbol(S, Decl(self-types-color.ts, 125, 21)) + + Split["length"] +>Split : Symbol(Split, Decl(self-types-color.ts, 113, 10)) +>S : Symbol(S, Decl(self-types-color.ts, 125, 21)) + + export type Shifted = +>Shifted : Symbol(Shifted, Decl(self-types-color.ts, 126, 22)) +>S : Symbol(S, Decl(self-types-color.ts, 128, 22)) + + S extends `${infer _}${infer T}` ? T : never +>S : Symbol(S, Decl(self-types-color.ts, 128, 22)) +>_ : Symbol(_, Decl(self-types-color.ts, 129, 22)) +>T : Symbol(T, Decl(self-types-color.ts, 129, 32)) +>T : Symbol(T, Decl(self-types-color.ts, 129, 32)) +} + +export namespace N { +>N : Symbol(N, Decl(self-types-color.ts, 130, 1)) + + export type Cast = A.Cast +>Cast : Symbol(Cast, Decl(self-types-color.ts, 132, 20)) +>T : Symbol(T, Decl(self-types-color.ts, 133, 19)) +>A : Symbol(A, Decl(self-types-color.ts, 177, 1)) +>Cast : Symbol(A.Cast, Decl(self-types-color.ts, 180, 20)) +>T : Symbol(T, Decl(self-types-color.ts, 133, 19)) + + export type NaturalNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; +>NaturalNumbers : Symbol(NaturalNumbers, Decl(self-types-color.ts, 133, 41)) + + export type WholeNumbers = [0, ...NaturalNumbers]; +>WholeNumbers : Symbol(WholeNumbers, Decl(self-types-color.ts, 135, 103)) +>NaturalNumbers : Symbol(NaturalNumbers, Decl(self-types-color.ts, 133, 41)) + + export type WholeNumbersUnshifted = [-1, ...WholeNumbers]; +>WholeNumbersUnshifted : Symbol(WholeNumbersUnshifted, Decl(self-types-color.ts, 136, 52)) +>WholeNumbers : Symbol(WholeNumbers, Decl(self-types-color.ts, 135, 103)) + + export type Increment = A.Get +>Increment : Symbol(Increment, Decl(self-types-color.ts, 137, 60)) +>N : Symbol(N, Decl(self-types-color.ts, 139, 24)) +>A : Symbol(A, Decl(self-types-color.ts, 177, 1)) +>Get : Symbol(A.Get, Decl(self-types-color.ts, 181, 47)) +>NaturalNumbers : Symbol(NaturalNumbers, Decl(self-types-color.ts, 133, 41)) +>N : Symbol(N, Decl(self-types-color.ts, 139, 24)) + + export type Decrement = A.Get +>Decrement : Symbol(Decrement, Decl(self-types-color.ts, 139, 53)) +>N : Symbol(N, Decl(self-types-color.ts, 140, 24)) +>A : Symbol(A, Decl(self-types-color.ts, 177, 1)) +>Get : Symbol(A.Get, Decl(self-types-color.ts, 181, 47)) +>WholeNumbersUnshifted : Symbol(WholeNumbersUnshifted, Decl(self-types-color.ts, 136, 52)) +>N : Symbol(N, Decl(self-types-color.ts, 140, 24)) +} + +export namespace L { +>L : Symbol(L, Decl(self-types-color.ts, 141, 1)) + + export type SlicedH = +>SlicedH : Symbol(SlicedH, Decl(self-types-color.ts, 143, 20)) +>A : Symbol(A, Decl(self-types-color.ts, 144, 22)) +>N : Symbol(N, Decl(self-types-color.ts, 144, 24)) + + N extends 0 ? [] : +>N : Symbol(N, Decl(self-types-color.ts, 144, 24)) + + A extends [infer H, ...infer T] ? [H, ...SlicedH>] : +>A : Symbol(A, Decl(self-types-color.ts, 144, 22)) +>H : Symbol(H, Decl(self-types-color.ts, 146, 20)) +>T : Symbol(T, Decl(self-types-color.ts, 146, 32)) +>H : Symbol(H, Decl(self-types-color.ts, 146, 20)) +>SlicedH : Symbol(SlicedH, Decl(self-types-color.ts, 143, 20)) +>T : Symbol(T, Decl(self-types-color.ts, 146, 32)) +>N : Symbol(N, Decl(self-types-color.ts, 130, 1)) +>Decrement : Symbol(N.Decrement, Decl(self-types-color.ts, 139, 53)) +>N : Symbol(N, Decl(self-types-color.ts, 144, 24)) + + never +} + +export namespace Nd { +>Nd : Symbol(Nd, Decl(self-types-color.ts, 148, 1)) + + export type IsLessThanOrEqual = +>IsLessThanOrEqual : Symbol(IsLessThanOrEqual, Decl(self-types-color.ts, 150, 21)) +>A : Symbol(A, Decl(self-types-color.ts, 151, 32)) +>B : Symbol(B, Decl(self-types-color.ts, 151, 34)) + + A extends 0 ? true : +>A : Symbol(A, Decl(self-types-color.ts, 151, 32)) + + B extends A.Get>, number> ? false : +>B : Symbol(B, Decl(self-types-color.ts, 151, 34)) +>A : Symbol(A, Decl(self-types-color.ts, 177, 1)) +>Get : Symbol(A.Get, Decl(self-types-color.ts, 181, 47)) +>L : Symbol(L, Decl(self-types-color.ts, 141, 1)) +>SlicedH : Symbol(L.SlicedH, Decl(self-types-color.ts, 143, 20)) +>N : Symbol(N, Decl(self-types-color.ts, 130, 1)) +>WholeNumbers : Symbol(N.WholeNumbers, Decl(self-types-color.ts, 135, 103)) +>N : Symbol(N, Decl(self-types-color.ts, 130, 1)) +>Increment : Symbol(N.Increment, Decl(self-types-color.ts, 137, 60)) +>A : Symbol(A, Decl(self-types-color.ts, 151, 32)) + + true + + export type IsLessThan = +>IsLessThan : Symbol(IsLessThan, Decl(self-types-color.ts, 154, 8)) +>A : Symbol(A, Decl(self-types-color.ts, 156, 25)) +>B : Symbol(B, Decl(self-types-color.ts, 156, 27)) + + A extends B ? false : +>A : Symbol(A, Decl(self-types-color.ts, 156, 25)) +>B : Symbol(B, Decl(self-types-color.ts, 156, 27)) + + IsLessThanOrEqual +>IsLessThanOrEqual : Symbol(IsLessThanOrEqual, Decl(self-types-color.ts, 150, 21)) +>A : Symbol(A, Decl(self-types-color.ts, 156, 25)) +>B : Symbol(B, Decl(self-types-color.ts, 156, 27)) +} + +export namespace Ns { +>Ns : Symbol(Ns, Decl(self-types-color.ts, 159, 1)) + + export type ToN = +>ToN : Symbol(ToN, Decl(self-types-color.ts, 161, 21)) +>T : Symbol(T, Decl(self-types-color.ts, 162, 18)) + + { [N in keyof N.WholeNumbers]: +>N : Symbol(N, Decl(self-types-color.ts, 163, 7)) +>N : Symbol(N, Decl(self-types-color.ts, 130, 1)) +>WholeNumbers : Symbol(N.WholeNumbers, Decl(self-types-color.ts, 135, 103)) + + T extends N ? N.WholeNumbers[N] : never +>T : Symbol(T, Decl(self-types-color.ts, 162, 18)) +>N : Symbol(N, Decl(self-types-color.ts, 163, 7)) +>N : Symbol(N, Decl(self-types-color.ts, 130, 1)) +>WholeNumbers : Symbol(N.WholeNumbers, Decl(self-types-color.ts, 135, 103)) +>N : Symbol(N, Decl(self-types-color.ts, 163, 7)) + + }[keyof N.WholeNumbers] +>N : Symbol(N, Decl(self-types-color.ts, 130, 1)) +>WholeNumbers : Symbol(N.WholeNumbers, Decl(self-types-color.ts, 135, 103)) + + export type TrimL = +>TrimL : Symbol(TrimL, Decl(self-types-color.ts, 165, 27)) +>T : Symbol(T, Decl(self-types-color.ts, 167, 20)) + + T extends `0${infer T}` ? TrimL : T +>T : Symbol(T, Decl(self-types-color.ts, 167, 20)) +>T : Symbol(T, Decl(self-types-color.ts, 168, 23)) +>TrimL : Symbol(TrimL, Decl(self-types-color.ts, 165, 27)) +>T : Symbol(T, Decl(self-types-color.ts, 168, 23)) +>T : Symbol(T, Decl(self-types-color.ts, 167, 20)) + + export type IsLessThanOrEqual<_A, _B, A = TrimL<_A>, B = TrimL<_B>> = +>IsLessThanOrEqual : Symbol(IsLessThanOrEqual, Decl(self-types-color.ts, 168, 42)) +>_A : Symbol(_A, Decl(self-types-color.ts, 170, 32)) +>_B : Symbol(_B, Decl(self-types-color.ts, 170, 35)) +>A : Symbol(A, Decl(self-types-color.ts, 170, 39)) +>TrimL : Symbol(TrimL, Decl(self-types-color.ts, 165, 27)) +>_A : Symbol(_A, Decl(self-types-color.ts, 170, 32)) +>B : Symbol(B, Decl(self-types-color.ts, 170, 54)) +>TrimL : Symbol(TrimL, Decl(self-types-color.ts, 165, 27)) +>_B : Symbol(_B, Decl(self-types-color.ts, 170, 35)) + + Nd.IsLessThan, S.Length> extends true ? true : +>Nd : Symbol(Nd, Decl(self-types-color.ts, 148, 1)) +>IsLessThan : Symbol(Nd.IsLessThan, Decl(self-types-color.ts, 154, 8)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Length : Symbol(S.Length, Decl(self-types-color.ts, 123, 44)) +>A : Symbol(A, Decl(self-types-color.ts, 170, 39)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Length : Symbol(S.Length, Decl(self-types-color.ts, 123, 44)) +>B : Symbol(B, Decl(self-types-color.ts, 170, 54)) + + S.Length extends S.Length +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Length : Symbol(S.Length, Decl(self-types-color.ts, 123, 44)) +>A : Symbol(A, Decl(self-types-color.ts, 170, 39)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Length : Symbol(S.Length, Decl(self-types-color.ts, 123, 44)) +>B : Symbol(B, Decl(self-types-color.ts, 170, 54)) + + ? Nd.IsLessThan>, ToN>> extends true ? true : +>Nd : Symbol(Nd, Decl(self-types-color.ts, 148, 1)) +>IsLessThan : Symbol(Nd.IsLessThan, Decl(self-types-color.ts, 154, 8)) +>ToN : Symbol(ToN, Decl(self-types-color.ts, 161, 21)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>At : Symbol(S.At, Decl(self-types-color.ts, 108, 21)) +>A : Symbol(A, Decl(self-types-color.ts, 170, 39)) +>ToN : Symbol(ToN, Decl(self-types-color.ts, 161, 21)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>At : Symbol(S.At, Decl(self-types-color.ts, 108, 21)) +>B : Symbol(B, Decl(self-types-color.ts, 170, 54)) + + S.At extends S.At ? IsLessThanOrEqual, S.Shifted> : +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>At : Symbol(S.At, Decl(self-types-color.ts, 108, 21)) +>A : Symbol(A, Decl(self-types-color.ts, 170, 39)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>At : Symbol(S.At, Decl(self-types-color.ts, 108, 21)) +>B : Symbol(B, Decl(self-types-color.ts, 170, 54)) +>IsLessThanOrEqual : Symbol(IsLessThanOrEqual, Decl(self-types-color.ts, 168, 42)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Shifted : Symbol(S.Shifted, Decl(self-types-color.ts, 126, 22)) +>A : Symbol(A, Decl(self-types-color.ts, 170, 39)) +>S : Symbol(S, Decl(self-types-color.ts, 96, 2200)) +>Shifted : Symbol(S.Shifted, Decl(self-types-color.ts, 126, 22)) +>B : Symbol(B, Decl(self-types-color.ts, 170, 54)) + + false : + false +} + + +export namespace A { +>A : Symbol(A, Decl(self-types-color.ts, 177, 1)) + + export type Cast = T extends U ? T : U; +>Cast : Symbol(Cast, Decl(self-types-color.ts, 180, 20)) +>T : Symbol(T, Decl(self-types-color.ts, 181, 19)) +>U : Symbol(U, Decl(self-types-color.ts, 181, 21)) +>T : Symbol(T, Decl(self-types-color.ts, 181, 19)) +>U : Symbol(U, Decl(self-types-color.ts, 181, 21)) +>T : Symbol(T, Decl(self-types-color.ts, 181, 19)) +>U : Symbol(U, Decl(self-types-color.ts, 181, 21)) + + export type Get = K extends keyof T ? T[K] : never +>Get : Symbol(Get, Decl(self-types-color.ts, 181, 47)) +>T : Symbol(T, Decl(self-types-color.ts, 182, 18)) +>K : Symbol(K, Decl(self-types-color.ts, 182, 20)) +>K : Symbol(K, Decl(self-types-color.ts, 182, 20)) +>T : Symbol(T, Decl(self-types-color.ts, 182, 18)) +>T : Symbol(T, Decl(self-types-color.ts, 182, 18)) +>K : Symbol(K, Decl(self-types-color.ts, 182, 20)) +} diff --git a/tests/baselines/reference/self-types-color.types b/tests/baselines/reference/self-types-color.types new file mode 100644 index 0000000000000..515ba1b26014a --- /dev/null +++ b/tests/baselines/reference/self-types-color.types @@ -0,0 +1,424 @@ +=== tests/cases/compiler/self-types-color.ts === +type Color = +>Color : Color + + self extends string + ? ParseColor extends infer R + ? R extends { error: infer E extends string } +>error : E + + ? Never<[`Type '${Print}' is not assignable to type 'Color'`, E]> + : R + : never + : string + +const t0: Color = 123 +>t0 : Color +>123 : 123 + +const t1: Color = "hello" as string +>t1 : Color +>"hello" as string : string +>"hello" : "hello" + +const t2: Color = "#fff" +>t2 : Color +>"#fff" : "#fff" + +const t3: Color = "#ffz" +>t3 : Color +>"#ffz" : "#ffz" + +const t4: Color = "rgb(100, 1000, 100)" +>t4 : Color +>"rgb(100, 1000, 100)" : "rgb(100, 1000, 100)" + +const t5 = "#fff" satisfies Color +>t5 : "#fff" +>"#fff" satisfies Color : "#fff" +>"#fff" : "#fff" + +const t6 = "#ffz" satisfies Color +>t6 : "#ffz" +>"#ffz" satisfies Color : "#ffz" +>"#ffz" : "#ffz" + +const t7 = "#fff" as Color +>t7 : Color +>"#fff" as Color : Color +>"#fff" : "#fff" + +const t8 = "#ffz" as Color +>t8 : Color +>"#ffz" as Color : Color +>"#ffz" : "#ffz" + +const t9 = "this is fine" as Color +>t9 : Color +>"this is fine" as Color : Color +>"this is fine" : "this is fine" + +const t10 = 0 as Color +>t10 : Color +>0 as Color : Color +>0 : 0 + + +type ParseColor = +>ParseColor : ParseColor + + S.IsStringLiteral extends false ? { error: "Expected a string literal" } : +>S : any +>false : false +>error : "Expected a string literal" + + T extends NamedColor ? T : + T extends `#${string}` ? ParseHexColor : + T extends `rgb${string}` ? ParseRgbColor : + { error: "Expected it to start with '#' or 'rgb' or be a named color" } +>error : "Expected it to start with '#' or 'rgb' or be a named color" + + +type ParseHexColor> = +>ParseHexColor : ParseHexColor +>S : any + + [I, C] extends [4, ""] | [7, ""] ? T : + I extends 0 | 1 | 2 | 3 | 4 | 5 | 6 + ? C extends (I extends 0 ? "#" : Hexadecimal) + ? ParseHexColor> +>N : any + + : { error: `Expected ${I extends 0 ? "#": "an hexadecimal character"} got '${S.Cast}' at column ${I}` } : +>error : `Expected ${I extends 0 ? "#" : "an hexadecimal character"} got '${A.Cast}' at column ${I}` +>S : any + + { error: `Unexpected character at ${N.Cast}` } +>error : `Unexpected character at ${A.Cast}` +>N : any + + +type Hexadecimal = +>Hexadecimal : "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" | "a" | "b" | "c" | "d" | "e" | "f" | "A" | "B" | "C" | "D" | "E" | "F" + + ( "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + | "a" | "b" | "c" | "d" | "e"| "f" + ) extends infer X + ? X | Uppercase> +>S : any + + : never + +type ParseRgbColor = +>ParseRgbColor : ParseRgbColor + + T extends `rgb${infer S}` + ? S extends `(${infer S}` + ? ParseNumberLessThanOrEqual, 255> extends infer X +>S : any + + ? X extends { error: infer E } ? { error: `${S.Cast} for red` } : +>error : E +>error : `${A.Cast} for red` +>S : any + + X extends { rest: infer S } ? +>rest : S + + S.TrimedL extends `,${infer S}` +>S : any + + ? ParseNumberLessThanOrEqual, 255> extends infer X +>S : any + + ? X extends { error: infer E } ? { error: `${S.Cast} for green` } : +>error : E +>error : `${A.Cast} for green` +>S : any + + X extends { rest: infer S } ? +>rest : S + + S.TrimedL extends `,${infer S}` +>S : any + + ? ParseNumberLessThanOrEqual, 255> extends infer X +>S : any + + ? X extends { error: infer E } ? { error: `${S.Cast} for blue` } : +>error : E +>error : `${A.Cast} for blue` +>S : any + + X extends { rest: infer S } ? +>rest : S + + S.TrimedR extends `)` +>S : any + + ? T + : { error: "Expected ')' after blue value at the end" } : +>error : "Expected ')' after blue value at the end" + + never + : never + : { error: "Expected ',' after green value" } : +>error : "Expected ',' after green value" + + never + : never + : { error: "Expected ',' after red value" } : +>error : "Expected ',' after red value" + + never + : never + : { error: `Expected '(' got ${S.Cast>} after rgb` } +>error : `Expected '(' got ${A.Cast, string>} after rgb` +>S : any +>S : any + + : { error: `Expected 'rgb' at the start` } +>error : "Expected 'rgb' at the start" + +type ParseNumberLessThanOrEqual, V = N["value" & keyof N]> = +>ParseNumberLessThanOrEqual : ParseNumberLessThanOrEqual + + N extends { error: unknown } ? N : +>error : unknown + + Ns.IsLessThanOrEqual extends true ? N : +>Ns : any +>true : true + + { error: `Expected value from '0' to '255' got '${S.Cast}'` } +>error : `Expected value from '0' to '255' got '${A.Cast}'` +>S : any + +type ParseNumber> = +>ParseNumber : ParseNumber + + D extends { value: infer Nh, rest: infer Sh } +>value : Nh +>rest : Sh + + ? ParseNumber extends infer X + ? X extends { value: infer Nt, rest: infer S } +>value : Nt +>rest : S + + ? { value: `${S.Cast}${S.Cast}`, rest: S } +>value : `${A.Cast}${A.Cast}` +>S : any +>S : any +>rest : S + + : { value: Nh, rest: Sh } +>value : Nh +>rest : Sh + + : never + : D + +type ParseDigit = +>ParseDigit : ParseDigit + + T extends `${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}${infer S}` + ? T extends `${infer V}${S}` + ? { value: `${V}`, rest: S } +>value : `${V}` +>rest : S + + : never + : { error: "Expected a number" } +>error : "Expected a number" + +type NamedColor = +>NamedColor : "black" | "silver" | "gray" | "white" | "maroon" | "red" | "purple" | "fuchsia" | "green" | "lime" | "olive" | "yellow" | "navy" | "blue" | "teal" | "aqua" | "aliceblue" | "antiquewhite" | "aquamarine" | "azure" | "beige" | "bisque" | "blanchedalmond" | "blueviolet" | "brown" | "burlywood" | "cadetblue" | "chartreuse" | "chocolate" | "coral" | "cornflowerblue" | "cornsilk" | "crimson" | "cyan" | "darkblue" | "darkcyan" | "darkgoldenrod" | "darkgray" | "darkgreen" | "darkgrey" | "darkkhaki" | "darkmagenta" | "darkolivegreen" | "darkorange" | "darkorchid" | "darkred" | "darksalmon" | "darkseagreen" | "darkslateblue" | "darkslategray" | "darkslategrey" | "darkturquoise" | "darkviolet" | "deeppink" | "deepskyblue" | "dimgray" | "dimgrey" | "dodgerblue" | "firebrick" | "floralwhite" | "forestgreen" | "gainsboro" | "ghostwhite" | "gold" | "goldenrod" | "greenyellow" | "grey" | "honeydew" | "hotpink" | "indianred" | "indigo" | "ivory" | "khaki" | "lavender" | "lavenderblush" | "lawngreen" | "lemonchiffon" | "lightblue" | "lightcoral" | "lightcyan" | "lightgoldenrodyellow" | "lightgray" | "lightgreen" | "lightgrey" | "lightpink" | "lightsalmon" | "lightseagreen" | "lightskyblue" | "lightslategray" | "lightslategrey" | "lightsteelblue" | "lightyellow" | "limegreen" | "linen" | "magenta" | "mediumaquamarine" | "mediumblue" | "mediumorchid" | "mediumpurple" | "mediumseagreen" | "mediumslateblue" | "mediumspringgreen" | "mediumturquoise" | "mediumvioletred" | "midnightblue" | "mintcream" | "mistyrose" | "moccasin" | "navajowhite" | "oldlace" | "olivedrab" | "orange" | "orangered" | "orchid" | "palegoldenrod" | "palegreen" | "paleturquoise" | "palevioletred" | "papayawhip" | "peachpuff" | "peru" | "pink" | "plum" | "powderblue" | "rosybrown" | "royalblue" | "saddlebrown" | "salmon" | "sandybrown" | "seagreen" | "seashell" | "sienna" | "skyblue" | "slateblue" | "slategray" | "slategrey" | "snow" | "springgreen" | "steelblue" | "tan" | "thistle" | "tomato" | "turquoise" | "violet" | "wheat" | "whitesmoke" | "yellowgreen" + + "black" | "silver" | "gray" | "white" | "maroon" | "red" | "purple" | "fuchsia" | "green" | "lime" | "olive" | "yellow" | "navy" | "blue" | "teal" | "aqua" | "aliceblue" | "antiquewhite" | "aqua" | "aquamarine" | "azure" | "beige" | "bisque" | "black" | "blanchedalmond" | "blue" | "blueviolet" | "brown" | "burlywood" | "cadetblue" | "chartreuse" | "chocolate" | "coral" | "cornflowerblue" | "cornsilk" | "crimson" | "cyan" | "darkblue" | "darkcyan" | "darkgoldenrod" | "darkgray" | "darkgreen" | "darkgrey" | "darkkhaki" | "darkmagenta" | "darkolivegreen" | "darkorange" | "darkorchid" | "darkred" | "darksalmon" | "darkseagreen" | "darkslateblue" | "darkslategray" | "darkslategrey" | "darkturquoise" | "darkviolet" | "deeppink" | "deepskyblue" | "dimgray" | "dimgrey" | "dodgerblue" | "firebrick" | "floralwhite" | "forestgreen" | "fuchsia" | "gainsboro" | "ghostwhite" | "gold" | "goldenrod" | "gray" | "green" | "greenyellow" | "grey" | "honeydew" | "hotpink" | "indianred" | "indigo" | "ivory" | "khaki" | "lavender" | "lavenderblush" | "lawngreen" | "lemonchiffon" | "lightblue" | "lightcoral" | "lightcyan" | "lightgoldenrodyellow" | "lightgray" | "lightgreen" | "lightgrey" | "lightpink" | "lightsalmon" | "lightseagreen" | "lightskyblue" | "lightslategray" | "lightslategrey" | "lightsteelblue" | "lightyellow" | "lime" | "limegreen" | "linen" | "magenta" | "maroon" | "mediumaquamarine" | "mediumblue" | "mediumorchid" | "mediumpurple" | "mediumseagreen" | "mediumslateblue" | "mediumspringgreen" | "mediumturquoise" | "mediumvioletred" | "midnightblue" | "mintcream" | "mistyrose" | "moccasin" | "navajowhite" | "navy" | "oldlace" | "olive" | "olivedrab" | "orange" | "orangered" | "orchid" | "palegoldenrod" | "palegreen" | "paleturquoise" | "palevioletred" | "papayawhip" | "peachpuff" | "peru" | "pink" | "plum" | "powderblue" | "purple" | "red" | "rosybrown" | "royalblue" | "saddlebrown" | "salmon" | "sandybrown" | "seagreen" | "seashell" | "sienna" | "silver" | "skyblue" | "slateblue" | "slategray" | "slategrey" | "snow" | "springgreen" | "steelblue" | "tan" | "teal" | "thistle" | "tomato" | "turquoise" | "violet" | "wheat" | "white" | "whitesmoke" | "yellow" | "yellowgreen" + +namespace S { + export type IsString = +>IsString : IsString + + T extends string ? true : false; +>true : true +>false : false + + export type IsStringLiteral = +>IsStringLiteral : IsStringLiteral + + IsString extends true +>true : true + + ? string extends T ? false : true +>false : false +>true : true + + : false +>false : false + + export type Cast = +>Cast : Cast + + A.Cast +>A : any + + export type At = +>At : At + + Split extends { [_ in A.Cast]: infer X } +>A : any + + ? X + : "" + + export type Split = +>Split : Split + + T extends `${infer H}${infer T}` ? [H, ...Split] : + T extends "" ? [] : [T] + + export type TrimedL = +>TrimedL : TrimedL + + T extends ` ${infer T}` ? TrimedL : T + + export type TrimedR = +>TrimedR : TrimedR + + T extends `${infer T} ` ? TrimedL : T + + export type Length = +>Length : Length + + Split["length"] + + export type Shifted = +>Shifted : Shifted + + S extends `${infer _}${infer T}` ? T : never +} + +export namespace N { + export type Cast = A.Cast +>Cast : Cast +>A : any + + export type NaturalNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; +>NaturalNumbers : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] + + export type WholeNumbers = [0, ...NaturalNumbers]; +>WholeNumbers : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] + + export type WholeNumbersUnshifted = [-1, ...WholeNumbers]; +>WholeNumbersUnshifted : [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] +>-1 : -1 +>1 : 1 + + export type Increment = A.Get +>Increment : Increment +>A : any + + export type Decrement = A.Get +>Decrement : Decrement +>A : any +} + +export namespace L { + export type SlicedH = +>SlicedH : SlicedH + + N extends 0 ? [] : + A extends [infer H, ...infer T] ? [H, ...SlicedH>] : +>N : any + + never +} + +export namespace Nd { + export type IsLessThanOrEqual = +>IsLessThanOrEqual : IsLessThanOrEqual + + A extends 0 ? true : +>true : true + + B extends A.Get>, number> ? false : +>A : any +>L : any +>N : any +>N : any +>false : false + + true +>true : true + + export type IsLessThan = +>IsLessThan : IsLessThan + + A extends B ? false : +>false : false + + IsLessThanOrEqual +} + +export namespace Ns { + export type ToN = +>ToN : ToN + + { [N in keyof N.WholeNumbers]: +>N : any + + T extends N ? N.WholeNumbers[N] : never +>N : any + + }[keyof N.WholeNumbers] +>N : any + + export type TrimL = +>TrimL : TrimL + + T extends `0${infer T}` ? TrimL : T + + export type IsLessThanOrEqual<_A, _B, A = TrimL<_A>, B = TrimL<_B>> = +>IsLessThanOrEqual : IsLessThanOrEqual<_A, _B, A, B> + + Nd.IsLessThan, S.Length> extends true ? true : +>Nd : any +>S : any +>S : any +>true : true +>true : true + + S.Length extends S.Length +>S : any +>S : any + + ? Nd.IsLessThan>, ToN>> extends true ? true : +>Nd : any +>S : any +>S : any +>true : true +>true : true + + S.At extends S.At ? IsLessThanOrEqual, S.Shifted> : +>S : any +>S : any +>S : any +>S : any + + false : +>false : false + + false +>false : false +} + + +export namespace A { + export type Cast = T extends U ? T : U; +>Cast : Cast + + export type Get = K extends keyof T ? T[K] : never +>Get : Get +} diff --git a/tests/baselines/reference/self-types-exact-flat.errors.txt b/tests/baselines/reference/self-types-exact-flat.errors.txt new file mode 100644 index 0000000000000..3778da2e34467 --- /dev/null +++ b/tests/baselines/reference/self-types-exact-flat.errors.txt @@ -0,0 +1,107 @@ +tests/cases/compiler/self-types-exact-flat.ts(3,3): error TS18051: Type '() => { a: { b: string; x: string; }; c: number; y: number; }' is not assignable to type 'Exact<() => { a: { b: string; }; c: number; }> + Excess properties found at .$result.a.x, and .$result.y +tests/cases/compiler/self-types-exact-flat.ts(14,5): error TS18051: Type '{ a: { b: number; c: string; d: string; }; }' is not assignable to type 'Exact<{ a: { b: number; }; }> + Excess properties found at .a.d, and .a.c +tests/cases/compiler/self-types-exact-flat.ts(18,5): error TS18051: Type '(x: { a: number; b: number; }) => { x: number; y: number; }' is not assignable to type 'Exact<(x: { a: number; b: number; c: number; }) => { x: number; }> + Excess properties found at .$parameters.0.c, and .$result.y + + +==== tests/cases/compiler/self-types-exact-flat.ts (3 errors) ==== + declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void + + f(() => ({ + ~~~~~~~~ + a: { + ~~~~~~ + b: "b", + ~~~~~~~~~~~ + x: "x" + ~~~~~~~~~~ + }, + ~~~~ + c: 0, + ~~~~~~~ + y: 1 + ~~~~~~ + })) + ~~ +!!! error TS18051: Type '() => { a: { b: string; x: string; }; c: number; y: number; }' is not assignable to type 'Exact<() => { a: { b: string; }; c: number; }> +!!! error TS18051: Excess properties found at .$result.a.x, and .$result.y + + let a0 = { a: { b: 1, c: "x", d: "y" } } + let t00: { a: { b: number } } = a0 + let t01: Exact<{ a: { b: number } }> = a0 + ~~~ +!!! error TS18051: Type '{ a: { b: number; c: string; d: string; }; }' is not assignable to type 'Exact<{ a: { b: number; }; }> +!!! error TS18051: Excess properties found at .a.d, and .a.c + + let a1 = (x: { a: number, b: number }) => ({ x: 0, y: 2 }) + let t10: (x: { a: number, b: number, c: number }) => { x: number } = a1 + let t11: Exact<(x: { a: number, b: number, c: number }) => { x: number }> = a1 + ~~~ +!!! error TS18051: Type '(x: { a: number; b: number; }) => { x: number; y: number; }' is not assignable to type 'Exact<(x: { a: number; b: number; c: number; }) => { x: number; }> +!!! error TS18051: Excess properties found at .$parameters.0.c, and .$result.y + + type Exact = + self extends T + ? ExactError extends infer E + ? [E] extends [never] + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'Exact<${Print}>`, + `Excess properties found at ${Join}` + ]> + : never + : T + + type ExactError = + A extends T + ? T extends unknown + ? A extends (...a: infer Aa) => infer Ar + ? T extends (...a: infer Ea) => infer Er + ? Prefix<".$parameters", ExactError> | Prefix<".$result", ExactError> + : never : + A extends object + ? T extends object + ? { [K in keyof A]: + K extends keyof T + ? Prefix<`.${PrintKey}`, ExactError> + : `.${PrintKey}` + }[A extends unknown[] ? number & keyof A : keyof A] + : never : + never + : never + : never + + type Join = + UIsUnit extends true ? `${And extends true ? "and " : ""}${T}` : + `${Cast, string | number>}, ${Join, true>}` + + type Prefix = + [B] extends [never] + ? B + : `${A & string}${B & string}` + + type PrintKey = + K extends symbol ? Print : K + + type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + + type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + + type UShifted = + Exclude> + + type UIsUnit = + [UShifted] extends [never] ? true : false + + type Cast = + T extends U ? T : U + + export {} \ No newline at end of file diff --git a/tests/baselines/reference/self-types-exact-flat.js b/tests/baselines/reference/self-types-exact-flat.js new file mode 100644 index 0000000000000..41088c664e61c --- /dev/null +++ b/tests/baselines/reference/self-types-exact-flat.js @@ -0,0 +1,101 @@ +//// [self-types-exact-flat.ts] +declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void + +f(() => ({ + a: { + b: "b", + x: "x" + }, + c: 0, + y: 1 +})) + +let a0 = { a: { b: 1, c: "x", d: "y" } } +let t00: { a: { b: number } } = a0 +let t01: Exact<{ a: { b: number } }> = a0 + +let a1 = (x: { a: number, b: number }) => ({ x: 0, y: 2 }) +let t10: (x: { a: number, b: number, c: number }) => { x: number } = a1 +let t11: Exact<(x: { a: number, b: number, c: number }) => { x: number }> = a1 + +type Exact = + self extends T + ? ExactError extends infer E + ? [E] extends [never] + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'Exact<${Print}>`, + `Excess properties found at ${Join}` + ]> + : never + : T + +type ExactError = + A extends T + ? T extends unknown + ? A extends (...a: infer Aa) => infer Ar + ? T extends (...a: infer Ea) => infer Er + ? Prefix<".$parameters", ExactError> | Prefix<".$result", ExactError> + : never : + A extends object + ? T extends object + ? { [K in keyof A]: + K extends keyof T + ? Prefix<`.${PrintKey}`, ExactError> + : `.${PrintKey}` + }[A extends unknown[] ? number & keyof A : keyof A] + : never : + never + : never + : never + +type Join = + UIsUnit extends true ? `${And extends true ? "and " : ""}${T}` : + `${Cast, string | number>}, ${Join, true>}` + +type Prefix = + [B] extends [never] + ? B + : `${A & string}${B & string}` + +type PrintKey = + K extends symbol ? Print : K + +type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + +type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + +type UShifted = + Exclude> + +type UIsUnit = + [UShifted] extends [never] ? true : false + +type Cast = + T extends U ? T : U + +export {} + +//// [self-types-exact-flat.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +f(function () { return ({ + a: { + b: "b", + x: "x" + }, + c: 0, + y: 1 +}); }); +var a0 = { a: { b: 1, c: "x", d: "y" } }; +var t00 = a0; +var t01 = a0; +var a1 = function (x) { return ({ x: 0, y: 2 }); }; +var t10 = a1; +var t11 = a1; diff --git a/tests/baselines/reference/self-types-exact-flat.symbols b/tests/baselines/reference/self-types-exact-flat.symbols new file mode 100644 index 0000000000000..1fdb25a60aab6 --- /dev/null +++ b/tests/baselines/reference/self-types-exact-flat.symbols @@ -0,0 +1,290 @@ +=== tests/cases/compiler/self-types-exact-flat.ts === +declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void +>f : Symbol(f, Decl(self-types-exact-flat.ts, 0, 13)) +>x : Symbol(x, Decl(self-types-exact-flat.ts, 0, 18)) +>Exact : Symbol(Exact, Decl(self-types-exact-flat.ts, 17, 78)) +>a : Symbol(a, Decl(self-types-exact-flat.ts, 0, 34)) +>b : Symbol(b, Decl(self-types-exact-flat.ts, 0, 39)) +>c : Symbol(c, Decl(self-types-exact-flat.ts, 0, 52)) + +f(() => ({ +>f : Symbol(f, Decl(self-types-exact-flat.ts, 0, 13)) + + a: { +>a : Symbol(a, Decl(self-types-exact-flat.ts, 2, 10)) + + b: "b", +>b : Symbol(b, Decl(self-types-exact-flat.ts, 3, 6)) + + x: "x" +>x : Symbol(x, Decl(self-types-exact-flat.ts, 4, 11)) + + }, + c: 0, +>c : Symbol(c, Decl(self-types-exact-flat.ts, 6, 4)) + + y: 1 +>y : Symbol(y, Decl(self-types-exact-flat.ts, 7, 7)) + +})) + +let a0 = { a: { b: 1, c: "x", d: "y" } } +>a0 : Symbol(a0, Decl(self-types-exact-flat.ts, 11, 3)) +>a : Symbol(a, Decl(self-types-exact-flat.ts, 11, 10)) +>b : Symbol(b, Decl(self-types-exact-flat.ts, 11, 15)) +>c : Symbol(c, Decl(self-types-exact-flat.ts, 11, 21)) +>d : Symbol(d, Decl(self-types-exact-flat.ts, 11, 29)) + +let t00: { a: { b: number } } = a0 +>t00 : Symbol(t00, Decl(self-types-exact-flat.ts, 12, 3)) +>a : Symbol(a, Decl(self-types-exact-flat.ts, 12, 10)) +>b : Symbol(b, Decl(self-types-exact-flat.ts, 12, 15)) +>a0 : Symbol(a0, Decl(self-types-exact-flat.ts, 11, 3)) + +let t01: Exact<{ a: { b: number } }> = a0 +>t01 : Symbol(t01, Decl(self-types-exact-flat.ts, 13, 3)) +>Exact : Symbol(Exact, Decl(self-types-exact-flat.ts, 17, 78)) +>a : Symbol(a, Decl(self-types-exact-flat.ts, 13, 16)) +>b : Symbol(b, Decl(self-types-exact-flat.ts, 13, 21)) +>a0 : Symbol(a0, Decl(self-types-exact-flat.ts, 11, 3)) + +let a1 = (x: { a: number, b: number }) => ({ x: 0, y: 2 }) +>a1 : Symbol(a1, Decl(self-types-exact-flat.ts, 15, 3)) +>x : Symbol(x, Decl(self-types-exact-flat.ts, 15, 10)) +>a : Symbol(a, Decl(self-types-exact-flat.ts, 15, 14)) +>b : Symbol(b, Decl(self-types-exact-flat.ts, 15, 25)) +>x : Symbol(x, Decl(self-types-exact-flat.ts, 15, 44)) +>y : Symbol(y, Decl(self-types-exact-flat.ts, 15, 50)) + +let t10: (x: { a: number, b: number, c: number }) => { x: number } = a1 +>t10 : Symbol(t10, Decl(self-types-exact-flat.ts, 16, 3)) +>x : Symbol(x, Decl(self-types-exact-flat.ts, 16, 10)) +>a : Symbol(a, Decl(self-types-exact-flat.ts, 16, 14)) +>b : Symbol(b, Decl(self-types-exact-flat.ts, 16, 25)) +>c : Symbol(c, Decl(self-types-exact-flat.ts, 16, 36)) +>x : Symbol(x, Decl(self-types-exact-flat.ts, 16, 54)) +>a1 : Symbol(a1, Decl(self-types-exact-flat.ts, 15, 3)) + +let t11: Exact<(x: { a: number, b: number, c: number }) => { x: number }> = a1 +>t11 : Symbol(t11, Decl(self-types-exact-flat.ts, 17, 3)) +>Exact : Symbol(Exact, Decl(self-types-exact-flat.ts, 17, 78)) +>x : Symbol(x, Decl(self-types-exact-flat.ts, 17, 16)) +>a : Symbol(a, Decl(self-types-exact-flat.ts, 17, 20)) +>b : Symbol(b, Decl(self-types-exact-flat.ts, 17, 31)) +>c : Symbol(c, Decl(self-types-exact-flat.ts, 17, 42)) +>x : Symbol(x, Decl(self-types-exact-flat.ts, 17, 60)) +>a1 : Symbol(a1, Decl(self-types-exact-flat.ts, 15, 3)) + +type Exact = +>Exact : Symbol(Exact, Decl(self-types-exact-flat.ts, 17, 78)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 19, 11)) + + self extends T +>T : Symbol(T, Decl(self-types-exact-flat.ts, 19, 11)) + + ? ExactError extends infer E +>ExactError : Symbol(ExactError, Decl(self-types-exact-flat.ts, 29, 7)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 19, 11)) +>E : Symbol(E, Decl(self-types-exact-flat.ts, 21, 39)) + + ? [E] extends [never] +>E : Symbol(E, Decl(self-types-exact-flat.ts, 21, 39)) + + ? self + : Never<[ +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) + + `Type '${Print}' is not assignable to type 'Exact<${Print}>`, +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 19, 11)) + + `Excess properties found at ${Join}` +>Join : Symbol(Join, Decl(self-types-exact-flat.ts, 48, 11)) +>E : Symbol(E, Decl(self-types-exact-flat.ts, 21, 39)) + + ]> + : never + : T +>T : Symbol(T, Decl(self-types-exact-flat.ts, 19, 11)) + +type ExactError = +>ExactError : Symbol(ExactError, Decl(self-types-exact-flat.ts, 29, 7)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 31, 16)) +>A : Symbol(A, Decl(self-types-exact-flat.ts, 31, 18)) + + A extends T +>A : Symbol(A, Decl(self-types-exact-flat.ts, 31, 18)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 31, 16)) + + ? T extends unknown +>T : Symbol(T, Decl(self-types-exact-flat.ts, 31, 16)) + + ? A extends (...a: infer Aa) => infer Ar +>A : Symbol(A, Decl(self-types-exact-flat.ts, 31, 18)) +>a : Symbol(a, Decl(self-types-exact-flat.ts, 34, 21)) +>Aa : Symbol(Aa, Decl(self-types-exact-flat.ts, 34, 32)) +>Ar : Symbol(Ar, Decl(self-types-exact-flat.ts, 34, 45)) + + ? T extends (...a: infer Ea) => infer Er +>T : Symbol(T, Decl(self-types-exact-flat.ts, 31, 16)) +>a : Symbol(a, Decl(self-types-exact-flat.ts, 35, 25)) +>Ea : Symbol(Ea, Decl(self-types-exact-flat.ts, 35, 36)) +>Er : Symbol(Er, Decl(self-types-exact-flat.ts, 35, 49)) + + ? Prefix<".$parameters", ExactError> | Prefix<".$result", ExactError> +>Prefix : Symbol(Prefix, Decl(self-types-exact-flat.ts, 52, 67)) +>ExactError : Symbol(ExactError, Decl(self-types-exact-flat.ts, 29, 7)) +>Aa : Symbol(Aa, Decl(self-types-exact-flat.ts, 34, 32)) +>Ea : Symbol(Ea, Decl(self-types-exact-flat.ts, 35, 36)) +>Prefix : Symbol(Prefix, Decl(self-types-exact-flat.ts, 52, 67)) +>ExactError : Symbol(ExactError, Decl(self-types-exact-flat.ts, 29, 7)) +>Er : Symbol(Er, Decl(self-types-exact-flat.ts, 35, 49)) +>Ar : Symbol(Ar, Decl(self-types-exact-flat.ts, 34, 45)) + + : never : + A extends object +>A : Symbol(A, Decl(self-types-exact-flat.ts, 31, 18)) + + ? T extends object +>T : Symbol(T, Decl(self-types-exact-flat.ts, 31, 16)) + + ? { [K in keyof A]: +>K : Symbol(K, Decl(self-types-exact-flat.ts, 40, 21)) +>A : Symbol(A, Decl(self-types-exact-flat.ts, 31, 18)) + + K extends keyof T +>K : Symbol(K, Decl(self-types-exact-flat.ts, 40, 21)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 31, 16)) + + ? Prefix<`.${PrintKey}`, ExactError> +>Prefix : Symbol(Prefix, Decl(self-types-exact-flat.ts, 52, 67)) +>PrintKey : Symbol(PrintKey, Decl(self-types-exact-flat.ts, 57, 34)) +>K : Symbol(K, Decl(self-types-exact-flat.ts, 40, 21)) +>ExactError : Symbol(ExactError, Decl(self-types-exact-flat.ts, 29, 7)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 31, 16)) +>K : Symbol(K, Decl(self-types-exact-flat.ts, 40, 21)) +>A : Symbol(A, Decl(self-types-exact-flat.ts, 31, 18)) +>K : Symbol(K, Decl(self-types-exact-flat.ts, 40, 21)) + + : `.${PrintKey}` +>PrintKey : Symbol(PrintKey, Decl(self-types-exact-flat.ts, 57, 34)) +>K : Symbol(K, Decl(self-types-exact-flat.ts, 40, 21)) + + }[A extends unknown[] ? number & keyof A : keyof A] +>A : Symbol(A, Decl(self-types-exact-flat.ts, 31, 18)) +>A : Symbol(A, Decl(self-types-exact-flat.ts, 31, 18)) +>A : Symbol(A, Decl(self-types-exact-flat.ts, 31, 18)) + + : never : + never + : never + : never + +type Join = +>Join : Symbol(Join, Decl(self-types-exact-flat.ts, 48, 11)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 50, 10)) +>And : Symbol(And, Decl(self-types-exact-flat.ts, 50, 27)) + + UIsUnit extends true ? `${And extends true ? "and " : ""}${T}` : +>UIsUnit : Symbol(UIsUnit, Decl(self-types-exact-flat.ts, 73, 23)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 50, 10)) +>And : Symbol(And, Decl(self-types-exact-flat.ts, 50, 27)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 50, 10)) + + `${Cast, string | number>}, ${Join, true>}` +>Cast : Symbol(Cast, Decl(self-types-exact-flat.ts, 76, 46)) +>UShift : Symbol(UShift, Decl(self-types-exact-flat.ts, 60, 33)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 50, 10)) +>Join : Symbol(Join, Decl(self-types-exact-flat.ts, 48, 11)) +>UShifted : Symbol(UShifted, Decl(self-types-exact-flat.ts, 70, 11)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 50, 10)) + +type Prefix = +>Prefix : Symbol(Prefix, Decl(self-types-exact-flat.ts, 52, 67)) +>A : Symbol(A, Decl(self-types-exact-flat.ts, 54, 12)) +>B : Symbol(B, Decl(self-types-exact-flat.ts, 54, 14)) + + [B] extends [never] +>B : Symbol(B, Decl(self-types-exact-flat.ts, 54, 14)) + + ? B +>B : Symbol(B, Decl(self-types-exact-flat.ts, 54, 14)) + + : `${A & string}${B & string}` +>A : Symbol(A, Decl(self-types-exact-flat.ts, 54, 12)) +>B : Symbol(B, Decl(self-types-exact-flat.ts, 54, 14)) + +type PrintKey = +>PrintKey : Symbol(PrintKey, Decl(self-types-exact-flat.ts, 57, 34)) +>K : Symbol(K, Decl(self-types-exact-flat.ts, 59, 14)) + + K extends symbol ? Print : K +>K : Symbol(K, Decl(self-types-exact-flat.ts, 59, 14)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(self-types-exact-flat.ts, 59, 14)) +>K : Symbol(K, Decl(self-types-exact-flat.ts, 59, 14)) + +type UShift = +>UShift : Symbol(UShift, Decl(self-types-exact-flat.ts, 60, 33)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 62, 12)) + + UToIntersection void : never> extends (_: infer H) => void +>UToIntersection : Symbol(UToIntersection, Decl(self-types-exact-flat.ts, 65, 11)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 62, 12)) +>x : Symbol(x, Decl(self-types-exact-flat.ts, 63, 39)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 62, 12)) +>_ : Symbol(_, Decl(self-types-exact-flat.ts, 63, 71)) +>H : Symbol(H, Decl(self-types-exact-flat.ts, 63, 79)) + + ? H +>H : Symbol(H, Decl(self-types-exact-flat.ts, 63, 79)) + + : never + +type UToIntersection = +>UToIntersection : Symbol(UToIntersection, Decl(self-types-exact-flat.ts, 65, 11)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 67, 21)) + + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 67, 21)) +>_ : Symbol(_, Decl(self-types-exact-flat.ts, 68, 24)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 67, 21)) +>_ : Symbol(_, Decl(self-types-exact-flat.ts, 68, 57)) +>I : Symbol(I, Decl(self-types-exact-flat.ts, 68, 65)) + + ? I +>I : Symbol(I, Decl(self-types-exact-flat.ts, 68, 65)) + + : never + +type UShifted = +>UShifted : Symbol(UShifted, Decl(self-types-exact-flat.ts, 70, 11)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 72, 14)) + + Exclude> +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 72, 14)) +>UShift : Symbol(UShift, Decl(self-types-exact-flat.ts, 60, 33)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 72, 14)) + +type UIsUnit = +>UIsUnit : Symbol(UIsUnit, Decl(self-types-exact-flat.ts, 73, 23)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 75, 13)) + + [UShifted] extends [never] ? true : false +>UShifted : Symbol(UShifted, Decl(self-types-exact-flat.ts, 70, 11)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 75, 13)) + +type Cast = +>Cast : Symbol(Cast, Decl(self-types-exact-flat.ts, 76, 46)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 78, 10)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 78, 12)) + + T extends U ? T : U +>T : Symbol(T, Decl(self-types-exact-flat.ts, 78, 10)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 78, 12)) +>T : Symbol(T, Decl(self-types-exact-flat.ts, 78, 10)) +>U : Symbol(U, Decl(self-types-exact-flat.ts, 78, 12)) + +export {} diff --git a/tests/baselines/reference/self-types-exact-flat.types b/tests/baselines/reference/self-types-exact-flat.types new file mode 100644 index 0000000000000..1d74bd8f8dd2a --- /dev/null +++ b/tests/baselines/reference/self-types-exact-flat.types @@ -0,0 +1,193 @@ +=== tests/cases/compiler/self-types-exact-flat.ts === +declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void +>f : (x: Exact<() => { a: { b: string; }; c: number;}>) => void +>x : Exact<() => { a: { b: string; }; c: number;}> +>a : { b: string; } +>b : string +>c : number + +f(() => ({ +>f(() => ({ a: { b: "b", x: "x" }, c: 0, y: 1})) : void +>f : (x: Exact<() => { a: { b: string; }; c: number; }>) => void +>() => ({ a: { b: "b", x: "x" }, c: 0, y: 1}) : () => { a: { b: string; x: string; }; c: number; y: number; } +>({ a: { b: "b", x: "x" }, c: 0, y: 1}) : { a: { b: string; x: string; }; c: number; y: number; } +>{ a: { b: "b", x: "x" }, c: 0, y: 1} : { a: { b: string; x: string; }; c: number; y: number; } + + a: { +>a : { b: string; x: string; } +>{ b: "b", x: "x" } : { b: string; x: string; } + + b: "b", +>b : string +>"b" : "b" + + x: "x" +>x : string +>"x" : "x" + + }, + c: 0, +>c : number +>0 : 0 + + y: 1 +>y : number +>1 : 1 + +})) + +let a0 = { a: { b: 1, c: "x", d: "y" } } +>a0 : { a: { b: number; c: string; d: string; }; } +>{ a: { b: 1, c: "x", d: "y" } } : { a: { b: number; c: string; d: string; }; } +>a : { b: number; c: string; d: string; } +>{ b: 1, c: "x", d: "y" } : { b: number; c: string; d: string; } +>b : number +>1 : 1 +>c : string +>"x" : "x" +>d : string +>"y" : "y" + +let t00: { a: { b: number } } = a0 +>t00 : { a: { b: number;}; } +>a : { b: number; } +>b : number +>a0 : { a: { b: number; c: string; d: string; }; } + +let t01: Exact<{ a: { b: number } }> = a0 +>t01 : Exact<{ a: { b: number;}; }> +>a : { b: number; } +>b : number +>a0 : { a: { b: number; c: string; d: string; }; } + +let a1 = (x: { a: number, b: number }) => ({ x: 0, y: 2 }) +>a1 : (x: { a: number; b: number;}) => { x: number; y: number; } +>(x: { a: number, b: number }) => ({ x: 0, y: 2 }) : (x: { a: number; b: number;}) => { x: number; y: number; } +>x : { a: number; b: number; } +>a : number +>b : number +>({ x: 0, y: 2 }) : { x: number; y: number; } +>{ x: 0, y: 2 } : { x: number; y: number; } +>x : number +>0 : 0 +>y : number +>2 : 2 + +let t10: (x: { a: number, b: number, c: number }) => { x: number } = a1 +>t10 : (x: { a: number; b: number; c: number;}) => { x: number; } +>x : { a: number; b: number; c: number; } +>a : number +>b : number +>c : number +>x : number +>a1 : (x: { a: number; b: number; }) => { x: number; y: number; } + +let t11: Exact<(x: { a: number, b: number, c: number }) => { x: number }> = a1 +>t11 : Exact<(x: { a: number; b: number; c: number;}) => { x: number; }> +>x : { a: number; b: number; c: number; } +>a : number +>b : number +>c : number +>x : number +>a1 : (x: { a: number; b: number; }) => { x: number; y: number; } + +type Exact = +>Exact : Exact + + self extends T + ? ExactError extends infer E + ? [E] extends [never] + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'Exact<${Print}>`, + `Excess properties found at ${Join}` + ]> + : never + : T + +type ExactError = +>ExactError : ExactError + + A extends T + ? T extends unknown + ? A extends (...a: infer Aa) => infer Ar +>a : Aa + + ? T extends (...a: infer Ea) => infer Er +>a : Ea + + ? Prefix<".$parameters", ExactError> | Prefix<".$result", ExactError> + : never : + A extends object + ? T extends object + ? { [K in keyof A]: + K extends keyof T + ? Prefix<`.${PrintKey}`, ExactError> + : `.${PrintKey}` + }[A extends unknown[] ? number & keyof A : keyof A] + : never : + never + : never + : never + +type Join = +>Join : Join +>false : false + + UIsUnit extends true ? `${And extends true ? "and " : ""}${T}` : +>true : true +>true : true + + `${Cast, string | number>}, ${Join, true>}` +>true : true + +type Prefix = +>Prefix : Prefix + + [B] extends [never] + ? B + : `${A & string}${B & string}` + +type PrintKey = +>PrintKey : PrintKey + + K extends symbol ? Print : K + +type UShift = +>UShift : UShift + + UToIntersection void : never> extends (_: infer H) => void +>x : U +>_ : H + + ? H + : never + +type UToIntersection = +>UToIntersection : UToIntersection + + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) +>_ : T +>_ : I + + ? I + : never + +type UShifted = +>UShifted : UShifted + + Exclude> + +type UIsUnit = +>UIsUnit : UIsUnit + + [UShifted] extends [never] ? true : false +>true : true +>false : false + +type Cast = +>Cast : Cast + + T extends U ? T : U + +export {} diff --git a/tests/baselines/reference/self-types-exact.errors.txt b/tests/baselines/reference/self-types-exact.errors.txt new file mode 100644 index 0000000000000..82005f11d23d5 --- /dev/null +++ b/tests/baselines/reference/self-types-exact.errors.txt @@ -0,0 +1,55 @@ +tests/cases/compiler/self-types-exact.ts(3,3): error TS2345: Argument of type '() => { a: { b: string; x: string; }; c: number; y: number; }' is not assignable to parameter of type '() => { a: { b: string; x: never; }; c: number; y: never; }'. + Call signature return types '{ a: { b: string; x: string; }; c: number; y: number; }' and '{ a: { b: string; x: never; }; c: number; y: never; }' are incompatible. + The types of 'a.x' are incompatible between these types. + Excess property 'x' not allowed as the target is an exact type + + +==== tests/cases/compiler/self-types-exact.ts (1 errors) ==== + declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void + + f(() => ({ + ~~~~~~~~ + a: { + ~~~~~~ + b: "b", + ~~~~~~~~~~~ + x: "x" + ~~~~~~~~~~ + }, + ~~~~ + c: 0, + ~~~~~~~ + y: 1 + ~~~~~~ + })) + ~~ +!!! error TS2345: Argument of type '() => { a: { b: string; x: string; }; c: number; y: number; }' is not assignable to parameter of type '() => { a: { b: string; x: never; }; c: number; y: never; }'. +!!! error TS2345: Call signature return types '{ a: { b: string; x: string; }; c: number; y: number; }' and '{ a: { b: string; x: never; }; c: number; y: never; }' are incompatible. +!!! error TS2345: The types of 'a.x' are incompatible between these types. +!!! error TS2345: Excess property 'x' not allowed as the target is an exact type + + type Exact = + _Exact + + // TODO: doesn't work if written as,,, + // type Exact = ... + + type _Exact = + A extends T + ? T extends unknown + ? A extends (...a: infer Aa) => infer Ar + ? T extends (...a: infer Ea) => infer Er + ? (...a: _Exact) => _Exact + : T : + A extends object + ? T extends object + ? { [K in keyof A]: + K extends keyof T ? _Exact : + Never<`Excess property '${K & string}' not allowed as the target is an exact type`> + } + : T : + T + : never + : T + + export {} \ No newline at end of file diff --git a/tests/baselines/reference/self-types-exact.js b/tests/baselines/reference/self-types-exact.js new file mode 100644 index 0000000000000..40657414edc5f --- /dev/null +++ b/tests/baselines/reference/self-types-exact.js @@ -0,0 +1,49 @@ +//// [self-types-exact.ts] +declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void + +f(() => ({ + a: { + b: "b", + x: "x" + }, + c: 0, + y: 1 +})) + +type Exact = + _Exact + +// TODO: doesn't work if written as,,, +// type Exact = ... + +type _Exact = + A extends T + ? T extends unknown + ? A extends (...a: infer Aa) => infer Ar + ? T extends (...a: infer Ea) => infer Er + ? (...a: _Exact) => _Exact + : T : + A extends object + ? T extends object + ? { [K in keyof A]: + K extends keyof T ? _Exact : + Never<`Excess property '${K & string}' not allowed as the target is an exact type`> + } + : T : + T + : never + : T + +export {} + +//// [self-types-exact.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +f(function () { return ({ + a: { + b: "b", + x: "x" + }, + c: 0, + y: 1 +}); }); diff --git a/tests/baselines/reference/self-types-exact.symbols b/tests/baselines/reference/self-types-exact.symbols new file mode 100644 index 0000000000000..19f354e8eee89 --- /dev/null +++ b/tests/baselines/reference/self-types-exact.symbols @@ -0,0 +1,111 @@ +=== tests/cases/compiler/self-types-exact.ts === +declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void +>f : Symbol(f, Decl(self-types-exact.ts, 0, 13)) +>x : Symbol(x, Decl(self-types-exact.ts, 0, 18)) +>Exact : Symbol(Exact, Decl(self-types-exact.ts, 9, 3)) +>a : Symbol(a, Decl(self-types-exact.ts, 0, 34)) +>b : Symbol(b, Decl(self-types-exact.ts, 0, 39)) +>c : Symbol(c, Decl(self-types-exact.ts, 0, 52)) + +f(() => ({ +>f : Symbol(f, Decl(self-types-exact.ts, 0, 13)) + + a: { +>a : Symbol(a, Decl(self-types-exact.ts, 2, 10)) + + b: "b", +>b : Symbol(b, Decl(self-types-exact.ts, 3, 6)) + + x: "x" +>x : Symbol(x, Decl(self-types-exact.ts, 4, 11)) + + }, + c: 0, +>c : Symbol(c, Decl(self-types-exact.ts, 6, 4)) + + y: 1 +>y : Symbol(y, Decl(self-types-exact.ts, 7, 7)) + +})) + +type Exact = +>Exact : Symbol(Exact, Decl(self-types-exact.ts, 9, 3)) +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) + + _Exact +>_Exact : Symbol(_Exact, Decl(self-types-exact.ts, 12, 17)) +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) + +// TODO: doesn't work if written as,,, +// type Exact = ... + +type _Exact = +>_Exact : Symbol(_Exact, Decl(self-types-exact.ts, 12, 17)) +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) +>A : Symbol(A, Decl(self-types-exact.ts, 17, 14)) + + A extends T +>A : Symbol(A, Decl(self-types-exact.ts, 17, 14)) +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) + + ? T extends unknown +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) + + ? A extends (...a: infer Aa) => infer Ar +>A : Symbol(A, Decl(self-types-exact.ts, 17, 14)) +>a : Symbol(a, Decl(self-types-exact.ts, 20, 21)) +>Aa : Symbol(Aa, Decl(self-types-exact.ts, 20, 32)) +>Ar : Symbol(Ar, Decl(self-types-exact.ts, 20, 45)) + + ? T extends (...a: infer Ea) => infer Er +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) +>a : Symbol(a, Decl(self-types-exact.ts, 21, 25)) +>Ea : Symbol(Ea, Decl(self-types-exact.ts, 21, 36)) +>Er : Symbol(Er, Decl(self-types-exact.ts, 21, 49)) + + ? (...a: _Exact) => _Exact +>a : Symbol(a, Decl(self-types-exact.ts, 22, 19)) +>_Exact : Symbol(_Exact, Decl(self-types-exact.ts, 12, 17)) +>Ea : Symbol(Ea, Decl(self-types-exact.ts, 21, 36)) +>Aa : Symbol(Aa, Decl(self-types-exact.ts, 20, 32)) +>_Exact : Symbol(_Exact, Decl(self-types-exact.ts, 12, 17)) +>Er : Symbol(Er, Decl(self-types-exact.ts, 21, 49)) +>Ar : Symbol(Ar, Decl(self-types-exact.ts, 20, 45)) + + : T : +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) + + A extends object +>A : Symbol(A, Decl(self-types-exact.ts, 17, 14)) + + ? T extends object +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) + + ? { [K in keyof A]: +>K : Symbol(K, Decl(self-types-exact.ts, 26, 21)) +>A : Symbol(A, Decl(self-types-exact.ts, 17, 14)) + + K extends keyof T ? _Exact : +>K : Symbol(K, Decl(self-types-exact.ts, 26, 21)) +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) +>_Exact : Symbol(_Exact, Decl(self-types-exact.ts, 12, 17)) +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) +>K : Symbol(K, Decl(self-types-exact.ts, 26, 21)) +>A : Symbol(A, Decl(self-types-exact.ts, 17, 14)) +>K : Symbol(K, Decl(self-types-exact.ts, 26, 21)) + + Never<`Excess property '${K & string}' not allowed as the target is an exact type`> +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(self-types-exact.ts, 26, 21)) + } + : T : +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) + + T +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) + + : never + : T +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) + +export {} diff --git a/tests/baselines/reference/self-types-exact.types b/tests/baselines/reference/self-types-exact.types new file mode 100644 index 0000000000000..1ff441f0b4975 --- /dev/null +++ b/tests/baselines/reference/self-types-exact.types @@ -0,0 +1,73 @@ +=== tests/cases/compiler/self-types-exact.ts === +declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void +>f : (x: Exact<() => { a: { b: string; }; c: number;}>) => void +>x : _Exact<() => { a: { b: string; }; c: number;}, self> +>a : { b: string; } +>b : string +>c : number + +f(() => ({ +>f(() => ({ a: { b: "b", x: "x" }, c: 0, y: 1})) : void +>f : (x: _Exact<() => { a: { b: string; }; c: number; }, self>) => void +>() => ({ a: { b: "b", x: "x" }, c: 0, y: 1}) : () => { a: { b: string; x: string; }; c: number; y: number; } +>({ a: { b: "b", x: "x" }, c: 0, y: 1}) : { a: { b: string; x: string; }; c: number; y: number; } +>{ a: { b: "b", x: "x" }, c: 0, y: 1} : { a: { b: string; x: string; }; c: number; y: number; } + + a: { +>a : { b: string; x: string; } +>{ b: "b", x: "x" } : { b: string; x: string; } + + b: "b", +>b : string +>"b" : "b" + + x: "x" +>x : string +>"x" : "x" + + }, + c: 0, +>c : number +>0 : 0 + + y: 1 +>y : number +>1 : 1 + +})) + +type Exact = +>Exact : Exact + + _Exact + +// TODO: doesn't work if written as,,, +// type Exact = ... + +type _Exact = +>_Exact : _Exact + + A extends T + ? T extends unknown + ? A extends (...a: infer Aa) => infer Ar +>a : Aa + + ? T extends (...a: infer Ea) => infer Er +>a : Ea + + ? (...a: _Exact) => _Exact +>a : _Exact + + : T : + A extends object + ? T extends object + ? { [K in keyof A]: + K extends keyof T ? _Exact : + Never<`Excess property '${K & string}' not allowed as the target is an exact type`> + } + : T : + T + : never + : T + +export {} diff --git a/tests/baselines/reference/self-types-json-simple.errors.txt b/tests/baselines/reference/self-types-json-simple.errors.txt new file mode 100644 index 0000000000000..df05b4602c94b --- /dev/null +++ b/tests/baselines/reference/self-types-json-simple.errors.txt @@ -0,0 +1,55 @@ +tests/cases/compiler/self-types-json-simple.ts(16,5): error TS2322: Type 'Node' is not assignable to type 'Json'. + Type 'Node' is not assignable to type '{ children: Json; parent: Json; }'. + Types of property 'children' are incompatible. + Type 'Node[]' is not assignable to type 'Json'. +tests/cases/compiler/self-types-json-simple.ts(17,16): error TS2322: Type '() => string' is not assignable to type 'Json'. +tests/cases/compiler/self-types-json-simple.ts(18,5): error TS2322: Type '{ x: () => string; }' is not assignable to type 'Json'. + Types of property 'x' are incompatible. + Type '() => string' is not assignable to type 'Json'. +tests/cases/compiler/self-types-json-simple.ts(24,20): error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2015' or later. + + +==== tests/cases/compiler/self-types-json-simple.ts (4 errors) ==== + type Json = + | string + | number + | boolean + | null + | { toJSON: () => string } + | (self extends unknown[] ? Json[] : self extends (...a: never[]) => unknown ? never : { [_ in keyof self]: Json }) + | (self extends (...a: never[]) => unknown ? Never<`Type '${Print}' is not assignable to type 'Json'`> : never) + + interface Node { + children: Node[] + parent: Node + } + let someNode = {} as Node + + let t1: Json = someNode // TODO: this should probably compile + ~~ +!!! error TS2322: Type 'Node' is not assignable to type 'Json'. +!!! error TS2322: Type 'Node' is not assignable to type '{ children: Json; parent: Json; }'. +!!! error TS2322: Types of property 'children' are incompatible. +!!! error TS2322: Type 'Node[]' is not assignable to type 'Json'. + let t3: Json = () => "hello" + ~~~~~~~~~~~~~ +!!! error TS2322: Type '() => string' is not assignable to type 'Json'. +!!! related TS6212 tests/cases/compiler/self-types-json-simple.ts:17:16: Did you mean to call this expression? + let t4: Json = { + ~~ +!!! error TS2322: Type '{ x: () => string; }' is not assignable to type 'Json'. +!!! error TS2322: Types of property 'x' are incompatible. +!!! error TS2322: Type '() => string' is not assignable to type 'Json'. + x: () => "hello" + } + let t5: Json = { + toJSON: () => "hello" + } + let t6: Json = new Map() + ~~~ +!!! error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2015' or later. + let t7: Json = ["hello", undefined] + let t8: Json = ["hello", null] as [string, null] + + export {} + \ No newline at end of file diff --git a/tests/baselines/reference/self-types-json-simple.js b/tests/baselines/reference/self-types-json-simple.js new file mode 100644 index 0000000000000..8dcaac5f45844 --- /dev/null +++ b/tests/baselines/reference/self-types-json-simple.js @@ -0,0 +1,46 @@ +//// [self-types-json-simple.ts] +type Json = + | string + | number + | boolean + | null + | { toJSON: () => string } + | (self extends unknown[] ? Json[] : self extends (...a: never[]) => unknown ? never : { [_ in keyof self]: Json }) + | (self extends (...a: never[]) => unknown ? Never<`Type '${Print}' is not assignable to type 'Json'`> : never) + +interface Node { + children: Node[] + parent: Node +} +let someNode = {} as Node + +let t1: Json = someNode // TODO: this should probably compile +let t3: Json = () => "hello" +let t4: Json = { + x: () => "hello" +} +let t5: Json = { + toJSON: () => "hello" +} +let t6: Json = new Map() +let t7: Json = ["hello", undefined] +let t8: Json = ["hello", null] as [string, null] + +export {} + + +//// [self-types-json-simple.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var someNode = {}; +var t1 = someNode; // TODO: this should probably compile +var t3 = function () { return "hello"; }; +var t4 = { + x: function () { return "hello"; } +}; +var t5 = { + toJSON: function () { return "hello"; } +}; +var t6 = new Map(); +var t7 = ["hello", undefined]; +var t8 = ["hello", null]; diff --git a/tests/baselines/reference/self-types-json-simple.symbols b/tests/baselines/reference/self-types-json-simple.symbols new file mode 100644 index 0000000000000..67a46de74a9c1 --- /dev/null +++ b/tests/baselines/reference/self-types-json-simple.symbols @@ -0,0 +1,75 @@ +=== tests/cases/compiler/self-types-json-simple.ts === +type Json = +>Json : Symbol(Json, Decl(self-types-json-simple.ts, 0, 0)) + + | string + | number + | boolean + | null + | { toJSON: () => string } +>toJSON : Symbol(toJSON, Decl(self-types-json-simple.ts, 5, 5)) + + | (self extends unknown[] ? Json[] : self extends (...a: never[]) => unknown ? never : { [_ in keyof self]: Json }) +>Json : Symbol(Json, Decl(self-types-json-simple.ts, 0, 0)) +>a : Symbol(a, Decl(self-types-json-simple.ts, 6, 53)) +>_ : Symbol(_, Decl(self-types-json-simple.ts, 6, 92)) +>Json : Symbol(Json, Decl(self-types-json-simple.ts, 0, 0)) + + | (self extends (...a: never[]) => unknown ? Never<`Type '${Print}' is not assignable to type 'Json'`> : never) +>a : Symbol(a, Decl(self-types-json-simple.ts, 7, 19)) +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) + +interface Node { +>Node : Symbol(Node, Decl(self-types-json-simple.ts, 7, 119)) + + children: Node[] +>children : Symbol(Node.children, Decl(self-types-json-simple.ts, 9, 16)) +>Node : Symbol(Node, Decl(self-types-json-simple.ts, 7, 119)) + + parent: Node +>parent : Symbol(Node.parent, Decl(self-types-json-simple.ts, 10, 18)) +>Node : Symbol(Node, Decl(self-types-json-simple.ts, 7, 119)) +} +let someNode = {} as Node +>someNode : Symbol(someNode, Decl(self-types-json-simple.ts, 13, 3)) +>Node : Symbol(Node, Decl(self-types-json-simple.ts, 7, 119)) + +let t1: Json = someNode // TODO: this should probably compile +>t1 : Symbol(t1, Decl(self-types-json-simple.ts, 15, 3)) +>Json : Symbol(Json, Decl(self-types-json-simple.ts, 0, 0)) +>someNode : Symbol(someNode, Decl(self-types-json-simple.ts, 13, 3)) + +let t3: Json = () => "hello" +>t3 : Symbol(t3, Decl(self-types-json-simple.ts, 16, 3)) +>Json : Symbol(Json, Decl(self-types-json-simple.ts, 0, 0)) + +let t4: Json = { +>t4 : Symbol(t4, Decl(self-types-json-simple.ts, 17, 3)) +>Json : Symbol(Json, Decl(self-types-json-simple.ts, 0, 0)) + + x: () => "hello" +>x : Symbol(x, Decl(self-types-json-simple.ts, 17, 16)) +} +let t5: Json = { +>t5 : Symbol(t5, Decl(self-types-json-simple.ts, 20, 3)) +>Json : Symbol(Json, Decl(self-types-json-simple.ts, 0, 0)) + + toJSON: () => "hello" +>toJSON : Symbol(toJSON, Decl(self-types-json-simple.ts, 20, 16)) +} +let t6: Json = new Map() +>t6 : Symbol(t6, Decl(self-types-json-simple.ts, 23, 3)) +>Json : Symbol(Json, Decl(self-types-json-simple.ts, 0, 0)) + +let t7: Json = ["hello", undefined] +>t7 : Symbol(t7, Decl(self-types-json-simple.ts, 24, 3)) +>Json : Symbol(Json, Decl(self-types-json-simple.ts, 0, 0)) +>undefined : Symbol(undefined) + +let t8: Json = ["hello", null] as [string, null] +>t8 : Symbol(t8, Decl(self-types-json-simple.ts, 25, 3)) +>Json : Symbol(Json, Decl(self-types-json-simple.ts, 0, 0)) + +export {} + diff --git a/tests/baselines/reference/self-types-json-simple.types b/tests/baselines/reference/self-types-json-simple.types new file mode 100644 index 0000000000000..3858c5181dda0 --- /dev/null +++ b/tests/baselines/reference/self-types-json-simple.types @@ -0,0 +1,79 @@ +=== tests/cases/compiler/self-types-json-simple.ts === +type Json = +>Json : Json + + | string + | number + | boolean + | null +>null : null + + | { toJSON: () => string } +>toJSON : () => string + + | (self extends unknown[] ? Json[] : self extends (...a: never[]) => unknown ? never : { [_ in keyof self]: Json }) +>a : never[] + + | (self extends (...a: never[]) => unknown ? Never<`Type '${Print}' is not assignable to type 'Json'`> : never) +>a : never[] + +interface Node { + children: Node[] +>children : Node[] + + parent: Node +>parent : Node +} +let someNode = {} as Node +>someNode : Node +>{} as Node : Node +>{} : {} + +let t1: Json = someNode // TODO: this should probably compile +>t1 : Json +>someNode : Node + +let t3: Json = () => "hello" +>t3 : Json +>() => "hello" : () => string +>"hello" : "hello" + +let t4: Json = { +>t4 : Json +>{ x: () => "hello"} : { x: () => string; } + + x: () => "hello" +>x : () => string +>() => "hello" : () => string +>"hello" : "hello" +} +let t5: Json = { +>t5 : Json +>{ toJSON: () => "hello"} : { toJSON: () => string; } + + toJSON: () => "hello" +>toJSON : () => string +>() => "hello" : () => string +>"hello" : "hello" +} +let t6: Json = new Map() +>t6 : Json +>new Map() : any +>Map : any + +let t7: Json = ["hello", undefined] +>t7 : Json +>["hello", undefined] : "hello"[] +>"hello" : "hello" +>undefined : undefined + +let t8: Json = ["hello", null] as [string, null] +>t8 : Json +>["hello", null] as [string, null] : [string, null] +>["hello", null] : [string, null] +>"hello" : "hello" +>null : null +>null : null + +export {} + diff --git a/tests/baselines/reference/self-types-json.errors.txt b/tests/baselines/reference/self-types-json.errors.txt new file mode 100644 index 0000000000000..0441cdb9ac196 --- /dev/null +++ b/tests/baselines/reference/self-types-json.errors.txt @@ -0,0 +1,97 @@ +tests/cases/compiler/self-types-json.ts(7,5): error TS18051: Type 'Node' is not assignable to type 'Json', as it possibly has circular references +tests/cases/compiler/self-types-json.ts(9,16): error TS18051: Type '() => string' is not assignable to type 'Json', as it is a function +tests/cases/compiler/self-types-json.ts(10,5): error TS18051: Type '{ x: () => string; }' is not assignable to type 'Json', as value at .x is a function +tests/cases/compiler/self-types-json.ts(16,5): error TS18051: Type 'any' is not assignable to type 'Json', as ${any} +tests/cases/compiler/self-types-json.ts(16,20): error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2015' or later. +tests/cases/compiler/self-types-json.ts(18,5): error TS18051: Type '[string, undefined]' is not assignable to type 'Json', as it possibly has circular references + + +==== tests/cases/compiler/self-types-json.ts (6 errors) ==== + interface Node { + children: Node[] + parent: Node + } + let someNode = {} as Node + + let t1: Json = someNode + ~~ +!!! error TS18051: Type 'Node' is not assignable to type 'Json', as it possibly has circular references + let t2: Json<"AllowPossiblyCircular"> = someNode + let t3: Json = () => "hello" + ~~~~~~~~~~~~~ +!!! error TS18051: Type '() => string' is not assignable to type 'Json', as it is a function +!!! related TS6212 tests/cases/compiler/self-types-json.ts:9:16: Did you mean to call this expression? + let t4: Json = { + ~~ +!!! error TS18051: Type '{ x: () => string; }' is not assignable to type 'Json', as value at .x is a function + x: () => "hello" + } + let t5: Json = { + toJSON: () => "hello" + } + let t6: Json = new Map() // TODO: fourslash doesn't seem to include Map + ~~ +!!! error TS18051: Type 'any' is not assignable to type 'Json', as ${any} + ~~~ +!!! error TS2583: Cannot find name 'Map'. Do you need to change your target library? Try changing the 'lib' compiler option to 'es2015' or later. + let t7: Json = ["hello", undefined] + let t8: Json = ["hello", undefined] as [string, undefined] + ~~ +!!! error TS18051: Type '[string, undefined]' is not assignable to type 'Json', as it possibly has circular references + let t9: Json<"AllowUndefined"> = ["hello", undefined] + + type Json = + JsonError extends infer E + ? [E] extends [never] + ? self + : Never<`Type '${Print}' is not assignable to type 'Json', as ${E & string}`> + : never + + type JsonError = + T extends (...a: never[]) => unknown + ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a function` : + T extends { toJSON: () => string } + ? never : + IsCircular extends true + ? "AllowPossiblyCircular" extends Flags + ? never + : `${IsTopLevel extends true ? "it " : ""}possibly has circular references` : + T extends object + ? UShift<{ [K in keyof T]: + JsonError extends infer E + ? [E] extends [never] + ? never + : `value at .${K extends symbol ? `(${Print})` : K} ${E & string}` + : never + }[T extends unknown[] ? number & keyof T : keyof T]> : + T extends undefined ? "AllowUndefined" extends Flags ? never : `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} undefined` : + T extends bigint ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a bigint` : + T extends symbol ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a symbol` : + never + + type IsCircular = + T extends Visited ? true : + T extends object + ? true extends { [K in keyof T]: IsCircular }[keyof T] + ? true + : false : + false + + type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + + type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + + type UShifted = + Exclude> + + type UIsUnit = + [UShifted] extends [never] ? true : false + + export {} + \ No newline at end of file diff --git a/tests/baselines/reference/self-types-json.js b/tests/baselines/reference/self-types-json.js new file mode 100644 index 0000000000000..d3dd61ab02185 --- /dev/null +++ b/tests/baselines/reference/self-types-json.js @@ -0,0 +1,94 @@ +//// [self-types-json.ts] +interface Node { + children: Node[] + parent: Node +} +let someNode = {} as Node + +let t1: Json = someNode +let t2: Json<"AllowPossiblyCircular"> = someNode +let t3: Json = () => "hello" +let t4: Json = { + x: () => "hello" +} +let t5: Json = { + toJSON: () => "hello" +} +let t6: Json = new Map() // TODO: fourslash doesn't seem to include Map +let t7: Json = ["hello", undefined] +let t8: Json = ["hello", undefined] as [string, undefined] +let t9: Json<"AllowUndefined"> = ["hello", undefined] + +type Json = + JsonError extends infer E + ? [E] extends [never] + ? self + : Never<`Type '${Print}' is not assignable to type 'Json', as ${E & string}`> + : never + +type JsonError = + T extends (...a: never[]) => unknown + ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a function` : + T extends { toJSON: () => string } + ? never : + IsCircular extends true + ? "AllowPossiblyCircular" extends Flags + ? never + : `${IsTopLevel extends true ? "it " : ""}possibly has circular references` : + T extends object + ? UShift<{ [K in keyof T]: + JsonError extends infer E + ? [E] extends [never] + ? never + : `value at .${K extends symbol ? `(${Print})` : K} ${E & string}` + : never + }[T extends unknown[] ? number & keyof T : keyof T]> : + T extends undefined ? "AllowUndefined" extends Flags ? never : `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} undefined` : + T extends bigint ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a bigint` : + T extends symbol ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a symbol` : + never + +type IsCircular = + T extends Visited ? true : + T extends object + ? true extends { [K in keyof T]: IsCircular }[keyof T] + ? true + : false : + false + +type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + +type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + +type UShifted = + Exclude> + +type UIsUnit = + [UShifted] extends [never] ? true : false + +export {} + + +//// [self-types-json.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var someNode = {}; +var t1 = someNode; +var t2 = someNode; +var t3 = function () { return "hello"; }; +var t4 = { + x: function () { return "hello"; } +}; +var t5 = { + toJSON: function () { return "hello"; } +}; +var t6 = new Map(); // TODO: fourslash doesn't seem to include Map +var t7 = ["hello", undefined]; +var t8 = ["hello", undefined]; +var t9 = ["hello", undefined]; diff --git a/tests/baselines/reference/self-types-json.symbols b/tests/baselines/reference/self-types-json.symbols new file mode 100644 index 0000000000000..ee9ae183ce803 --- /dev/null +++ b/tests/baselines/reference/self-types-json.symbols @@ -0,0 +1,248 @@ +=== tests/cases/compiler/self-types-json.ts === +interface Node { +>Node : Symbol(Node, Decl(self-types-json.ts, 0, 0)) + + children: Node[] +>children : Symbol(Node.children, Decl(self-types-json.ts, 0, 16)) +>Node : Symbol(Node, Decl(self-types-json.ts, 0, 0)) + + parent: Node +>parent : Symbol(Node.parent, Decl(self-types-json.ts, 1, 18)) +>Node : Symbol(Node, Decl(self-types-json.ts, 0, 0)) +} +let someNode = {} as Node +>someNode : Symbol(someNode, Decl(self-types-json.ts, 4, 3)) +>Node : Symbol(Node, Decl(self-types-json.ts, 0, 0)) + +let t1: Json = someNode +>t1 : Symbol(t1, Decl(self-types-json.ts, 6, 3)) +>Json : Symbol(Json, Decl(self-types-json.ts, 18, 53)) +>someNode : Symbol(someNode, Decl(self-types-json.ts, 4, 3)) + +let t2: Json<"AllowPossiblyCircular"> = someNode +>t2 : Symbol(t2, Decl(self-types-json.ts, 7, 3)) +>Json : Symbol(Json, Decl(self-types-json.ts, 18, 53)) +>someNode : Symbol(someNode, Decl(self-types-json.ts, 4, 3)) + +let t3: Json = () => "hello" +>t3 : Symbol(t3, Decl(self-types-json.ts, 8, 3)) +>Json : Symbol(Json, Decl(self-types-json.ts, 18, 53)) + +let t4: Json = { +>t4 : Symbol(t4, Decl(self-types-json.ts, 9, 3)) +>Json : Symbol(Json, Decl(self-types-json.ts, 18, 53)) + + x: () => "hello" +>x : Symbol(x, Decl(self-types-json.ts, 9, 16)) +} +let t5: Json = { +>t5 : Symbol(t5, Decl(self-types-json.ts, 12, 3)) +>Json : Symbol(Json, Decl(self-types-json.ts, 18, 53)) + + toJSON: () => "hello" +>toJSON : Symbol(toJSON, Decl(self-types-json.ts, 12, 16)) +} +let t6: Json = new Map() // TODO: fourslash doesn't seem to include Map +>t6 : Symbol(t6, Decl(self-types-json.ts, 15, 3)) +>Json : Symbol(Json, Decl(self-types-json.ts, 18, 53)) + +let t7: Json = ["hello", undefined] +>t7 : Symbol(t7, Decl(self-types-json.ts, 16, 3)) +>Json : Symbol(Json, Decl(self-types-json.ts, 18, 53)) +>undefined : Symbol(undefined) + +let t8: Json = ["hello", undefined] as [string, undefined] +>t8 : Symbol(t8, Decl(self-types-json.ts, 17, 3)) +>Json : Symbol(Json, Decl(self-types-json.ts, 18, 53)) +>undefined : Symbol(undefined) + +let t9: Json<"AllowUndefined"> = ["hello", undefined] +>t9 : Symbol(t9, Decl(self-types-json.ts, 18, 3)) +>Json : Symbol(Json, Decl(self-types-json.ts, 18, 53)) +>undefined : Symbol(undefined) + +type Json = +>Json : Symbol(Json, Decl(self-types-json.ts, 18, 53)) +>Flags : Symbol(Flags, Decl(self-types-json.ts, 20, 10)) + + JsonError extends infer E +>JsonError : Symbol(JsonError, Decl(self-types-json.ts, 25, 11)) +>Flags : Symbol(Flags, Decl(self-types-json.ts, 20, 10)) +>E : Symbol(E, Decl(self-types-json.ts, 21, 38)) + + ? [E] extends [never] +>E : Symbol(E, Decl(self-types-json.ts, 21, 38)) + + ? self + : Never<`Type '${Print}' is not assignable to type 'Json', as ${E & string}`> +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>E : Symbol(E, Decl(self-types-json.ts, 21, 38)) + + : never + +type JsonError = +>JsonError : Symbol(JsonError, Decl(self-types-json.ts, 25, 11)) +>Flags : Symbol(Flags, Decl(self-types-json.ts, 27, 15)) +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) +>IsTopLevel : Symbol(IsTopLevel, Decl(self-types-json.ts, 27, 24)) +>TCopy : Symbol(TCopy, Decl(self-types-json.ts, 27, 43)) +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) + + T extends (...a: never[]) => unknown +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) +>a : Symbol(a, Decl(self-types-json.ts, 28, 13)) + + ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a function` : +>IsTopLevel : Symbol(IsTopLevel, Decl(self-types-json.ts, 27, 24)) +>UIsUnit : Symbol(UIsUnit, Decl(self-types-json.ts, 68, 23)) +>TCopy : Symbol(TCopy, Decl(self-types-json.ts, 27, 43)) + + T extends { toJSON: () => string } +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) +>toJSON : Symbol(toJSON, Decl(self-types-json.ts, 30, 13)) + + ? never : + IsCircular extends true +>IsCircular : Symbol(IsCircular, Decl(self-types-json.ts, 47, 7)) +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) + + ? "AllowPossiblyCircular" extends Flags +>Flags : Symbol(Flags, Decl(self-types-json.ts, 27, 15)) + + ? never + : `${IsTopLevel extends true ? "it " : ""}possibly has circular references` : +>IsTopLevel : Symbol(IsTopLevel, Decl(self-types-json.ts, 27, 24)) + + T extends object +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) + + ? UShift<{ [K in keyof T]: +>UShift : Symbol(UShift, Decl(self-types-json.ts, 55, 7)) +>K : Symbol(K, Decl(self-types-json.ts, 37, 16)) +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) + + JsonError extends infer E +>JsonError : Symbol(JsonError, Decl(self-types-json.ts, 25, 11)) +>Flags : Symbol(Flags, Decl(self-types-json.ts, 27, 15)) +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) +>K : Symbol(K, Decl(self-types-json.ts, 37, 16)) +>E : Symbol(E, Decl(self-types-json.ts, 38, 51)) + + ? [E] extends [never] +>E : Symbol(E, Decl(self-types-json.ts, 38, 51)) + + ? never + : `value at .${K extends symbol ? `(${Print})` : K} ${E & string}` +>K : Symbol(K, Decl(self-types-json.ts, 37, 16)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(self-types-json.ts, 37, 16)) +>K : Symbol(K, Decl(self-types-json.ts, 37, 16)) +>E : Symbol(E, Decl(self-types-json.ts, 38, 51)) + + : never + }[T extends unknown[] ? number & keyof T : keyof T]> : +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) + + T extends undefined ? "AllowUndefined" extends Flags ? never : `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} undefined` : +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) +>Flags : Symbol(Flags, Decl(self-types-json.ts, 27, 15)) +>IsTopLevel : Symbol(IsTopLevel, Decl(self-types-json.ts, 27, 24)) +>UIsUnit : Symbol(UIsUnit, Decl(self-types-json.ts, 68, 23)) +>TCopy : Symbol(TCopy, Decl(self-types-json.ts, 27, 43)) + + T extends bigint ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a bigint` : +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) +>IsTopLevel : Symbol(IsTopLevel, Decl(self-types-json.ts, 27, 24)) +>UIsUnit : Symbol(UIsUnit, Decl(self-types-json.ts, 68, 23)) +>TCopy : Symbol(TCopy, Decl(self-types-json.ts, 27, 43)) + + T extends symbol ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a symbol` : +>T : Symbol(T, Decl(self-types-json.ts, 27, 21)) +>IsTopLevel : Symbol(IsTopLevel, Decl(self-types-json.ts, 27, 24)) +>UIsUnit : Symbol(UIsUnit, Decl(self-types-json.ts, 68, 23)) +>TCopy : Symbol(TCopy, Decl(self-types-json.ts, 27, 43)) + + never + +type IsCircular = +>IsCircular : Symbol(IsCircular, Decl(self-types-json.ts, 47, 7)) +>T : Symbol(T, Decl(self-types-json.ts, 49, 16)) +>Visited : Symbol(Visited, Decl(self-types-json.ts, 49, 18)) + + T extends Visited ? true : +>T : Symbol(T, Decl(self-types-json.ts, 49, 16)) +>Visited : Symbol(Visited, Decl(self-types-json.ts, 49, 18)) + + T extends object +>T : Symbol(T, Decl(self-types-json.ts, 49, 16)) + + ? true extends { [K in keyof T]: IsCircular }[keyof T] +>K : Symbol(K, Decl(self-types-json.ts, 52, 22)) +>T : Symbol(T, Decl(self-types-json.ts, 49, 16)) +>IsCircular : Symbol(IsCircular, Decl(self-types-json.ts, 47, 7)) +>T : Symbol(T, Decl(self-types-json.ts, 49, 16)) +>K : Symbol(K, Decl(self-types-json.ts, 52, 22)) +>Visited : Symbol(Visited, Decl(self-types-json.ts, 49, 18)) +>T : Symbol(T, Decl(self-types-json.ts, 49, 16)) +>T : Symbol(T, Decl(self-types-json.ts, 49, 16)) + + ? true + : false : + false + +type UShift = +>UShift : Symbol(UShift, Decl(self-types-json.ts, 55, 7)) +>U : Symbol(U, Decl(self-types-json.ts, 57, 12)) + + UToIntersection void : never> extends (_: infer H) => void +>UToIntersection : Symbol(UToIntersection, Decl(self-types-json.ts, 60, 11)) +>U : Symbol(U, Decl(self-types-json.ts, 57, 12)) +>x : Symbol(x, Decl(self-types-json.ts, 58, 39)) +>U : Symbol(U, Decl(self-types-json.ts, 57, 12)) +>_ : Symbol(_, Decl(self-types-json.ts, 58, 71)) +>H : Symbol(H, Decl(self-types-json.ts, 58, 79)) + + ? H +>H : Symbol(H, Decl(self-types-json.ts, 58, 79)) + + : never + +type UToIntersection = +>UToIntersection : Symbol(UToIntersection, Decl(self-types-json.ts, 60, 11)) +>T : Symbol(T, Decl(self-types-json.ts, 62, 21)) + + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) +>T : Symbol(T, Decl(self-types-json.ts, 62, 21)) +>_ : Symbol(_, Decl(self-types-json.ts, 63, 24)) +>T : Symbol(T, Decl(self-types-json.ts, 62, 21)) +>_ : Symbol(_, Decl(self-types-json.ts, 63, 57)) +>I : Symbol(I, Decl(self-types-json.ts, 63, 65)) + + ? I +>I : Symbol(I, Decl(self-types-json.ts, 63, 65)) + + : never + +type UShifted = +>UShifted : Symbol(UShifted, Decl(self-types-json.ts, 65, 11)) +>U : Symbol(U, Decl(self-types-json.ts, 67, 14)) + + Exclude> +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(self-types-json.ts, 67, 14)) +>UShift : Symbol(UShift, Decl(self-types-json.ts, 55, 7)) +>U : Symbol(U, Decl(self-types-json.ts, 67, 14)) + +type UIsUnit = +>UIsUnit : Symbol(UIsUnit, Decl(self-types-json.ts, 68, 23)) +>U : Symbol(U, Decl(self-types-json.ts, 70, 13)) + + [UShifted] extends [never] ? true : false +>UShifted : Symbol(UShifted, Decl(self-types-json.ts, 65, 11)) +>U : Symbol(U, Decl(self-types-json.ts, 70, 13)) + +export {} + diff --git a/tests/baselines/reference/self-types-json.types b/tests/baselines/reference/self-types-json.types new file mode 100644 index 0000000000000..b0370400d21fe --- /dev/null +++ b/tests/baselines/reference/self-types-json.types @@ -0,0 +1,177 @@ +=== tests/cases/compiler/self-types-json.ts === +interface Node { + children: Node[] +>children : Node[] + + parent: Node +>parent : Node +} +let someNode = {} as Node +>someNode : Node +>{} as Node : Node +>{} : {} + +let t1: Json = someNode +>t1 : Json +>someNode : Node + +let t2: Json<"AllowPossiblyCircular"> = someNode +>t2 : Json<"AllowPossiblyCircular"> +>someNode : Node + +let t3: Json = () => "hello" +>t3 : Json +>() => "hello" : () => string +>"hello" : "hello" + +let t4: Json = { +>t4 : Json +>{ x: () => "hello"} : { x: () => string; } + + x: () => "hello" +>x : () => string +>() => "hello" : () => string +>"hello" : "hello" +} +let t5: Json = { +>t5 : Json +>{ toJSON: () => "hello"} : { toJSON: () => string; } + + toJSON: () => "hello" +>toJSON : () => string +>() => "hello" : () => string +>"hello" : "hello" +} +let t6: Json = new Map() // TODO: fourslash doesn't seem to include Map +>t6 : Json +>new Map() : any +>Map : any + +let t7: Json = ["hello", undefined] +>t7 : Json +>["hello", undefined] : string[] +>"hello" : "hello" +>undefined : undefined + +let t8: Json = ["hello", undefined] as [string, undefined] +>t8 : Json +>["hello", undefined] as [string, undefined] : [string, undefined] +>["hello", undefined] : [string, undefined] +>"hello" : "hello" +>undefined : undefined + +let t9: Json<"AllowUndefined"> = ["hello", undefined] +>t9 : Json<"AllowUndefined"> +>["hello", undefined] : string[] +>"hello" : "hello" +>undefined : undefined + +type Json = +>Json : Json + + JsonError extends infer E + ? [E] extends [never] + ? self + : Never<`Type '${Print}' is not assignable to type 'Json', as ${E & string}`> + : never + +type JsonError = +>JsonError : JsonError +>true : true + + T extends (...a: never[]) => unknown +>a : never[] + + ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a function` : +>true : true +>true : true + + T extends { toJSON: () => string } +>toJSON : () => string + + ? never : + IsCircular extends true +>true : true + + ? "AllowPossiblyCircular" extends Flags + ? never + : `${IsTopLevel extends true ? "it " : ""}possibly has circular references` : +>true : true + + T extends object + ? UShift<{ [K in keyof T]: + JsonError extends infer E +>false : false + + ? [E] extends [never] + ? never + : `value at .${K extends symbol ? `(${Print})` : K} ${E & string}` + : never + }[T extends unknown[] ? number & keyof T : keyof T]> : + T extends undefined ? "AllowUndefined" extends Flags ? never : `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} undefined` : +>true : true +>true : true + + T extends bigint ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a bigint` : +>true : true +>true : true + + T extends symbol ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a symbol` : +>true : true +>true : true + + never + +type IsCircular = +>IsCircular : IsCircular + + T extends Visited ? true : +>true : true + + T extends object + ? true extends { [K in keyof T]: IsCircular }[keyof T] +>true : true + + ? true +>true : true + + : false : +>false : false + + false +>false : false + +type UShift = +>UShift : UShift + + UToIntersection void : never> extends (_: infer H) => void +>x : U +>_ : H + + ? H + : never + +type UToIntersection = +>UToIntersection : UToIntersection + + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) +>_ : T +>_ : I + + ? I + : never + +type UShifted = +>UShifted : UShifted + + Exclude> + +type UIsUnit = +>UIsUnit : UIsUnit + + [UShifted] extends [never] ? true : false +>true : true +>false : false + +export {} + diff --git a/tests/baselines/reference/self-types-keyof.errors.txt b/tests/baselines/reference/self-types-keyof.errors.txt new file mode 100644 index 0000000000000..bcced2f0816e5 --- /dev/null +++ b/tests/baselines/reference/self-types-keyof.errors.txt @@ -0,0 +1,30 @@ +tests/cases/compiler/self-types-keyof.ts(11,5): error TS18051: Type '"b"' can't be used to index type '{ a: number; }' +tests/cases/compiler/self-types-keyof.ts(18,25): error TS18051: Type '"b"' can't be used to index type '{ a: number; }' + + +==== tests/cases/compiler/self-types-keyof.ts (2 errors) ==== + // Implementing index types without index types + + type KeyOf = + self extends string | number | symbol + ? T extends { [_ in self]: unknown } + ? self + : Never<`Type '${Print}' can't be used to index type '${Print}'`> + : string | number | symbol + + let t0: KeyOf<{ a: number }> = "a" + let t1: KeyOf<{ a: number }> = "b" + ~~ +!!! error TS18051: Type '"b"' can't be used to index type '{ a: number; }' + + declare const get: + >(t: T, k: K) => + T extends { [_ in K]: infer X } ? X : never + + let t3: number = get({ a: 10 }, "a") + let t4 = get({ a: 10 }, "b") + ~~~ +!!! error TS18051: Type '"b"' can't be used to index type '{ a: number; }' + + export {} + \ No newline at end of file diff --git a/tests/baselines/reference/self-types-keyof.js b/tests/baselines/reference/self-types-keyof.js new file mode 100644 index 0000000000000..0d253326a09f1 --- /dev/null +++ b/tests/baselines/reference/self-types-keyof.js @@ -0,0 +1,31 @@ +//// [self-types-keyof.ts] +// Implementing index types without index types + +type KeyOf = + self extends string | number | symbol + ? T extends { [_ in self]: unknown } + ? self + : Never<`Type '${Print}' can't be used to index type '${Print}'`> + : string | number | symbol + +let t0: KeyOf<{ a: number }> = "a" +let t1: KeyOf<{ a: number }> = "b" + +declare const get: + >(t: T, k: K) => + T extends { [_ in K]: infer X } ? X : never + +let t3: number = get({ a: 10 }, "a") +let t4 = get({ a: 10 }, "b") + +export {} + + +//// [self-types-keyof.js] +"use strict"; +// Implementing index types without index types +Object.defineProperty(exports, "__esModule", { value: true }); +var t0 = "a"; +var t1 = "b"; +var t3 = get({ a: 10 }, "a"); +var t4 = get({ a: 10 }, "b"); diff --git a/tests/baselines/reference/self-types-keyof.symbols b/tests/baselines/reference/self-types-keyof.symbols new file mode 100644 index 0000000000000..d3cd44978768f --- /dev/null +++ b/tests/baselines/reference/self-types-keyof.symbols @@ -0,0 +1,63 @@ +=== tests/cases/compiler/self-types-keyof.ts === +// Implementing index types without index types + +type KeyOf = +>KeyOf : Symbol(KeyOf, Decl(self-types-keyof.ts, 0, 0)) +>T : Symbol(T, Decl(self-types-keyof.ts, 2, 11)) + + self extends string | number | symbol + ? T extends { [_ in self]: unknown } +>T : Symbol(T, Decl(self-types-keyof.ts, 2, 11)) +>_ : Symbol(_, Decl(self-types-keyof.ts, 4, 19)) + + ? self + : Never<`Type '${Print}' can't be used to index type '${Print}'`> +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-keyof.ts, 2, 11)) + + : string | number | symbol + +let t0: KeyOf<{ a: number }> = "a" +>t0 : Symbol(t0, Decl(self-types-keyof.ts, 9, 3)) +>KeyOf : Symbol(KeyOf, Decl(self-types-keyof.ts, 0, 0)) +>a : Symbol(a, Decl(self-types-keyof.ts, 9, 15)) + +let t1: KeyOf<{ a: number }> = "b" +>t1 : Symbol(t1, Decl(self-types-keyof.ts, 10, 3)) +>KeyOf : Symbol(KeyOf, Decl(self-types-keyof.ts, 0, 0)) +>a : Symbol(a, Decl(self-types-keyof.ts, 10, 15)) + +declare const get: +>get : Symbol(get, Decl(self-types-keyof.ts, 12, 13)) + + >(t: T, k: K) => +>T : Symbol(T, Decl(self-types-keyof.ts, 13, 3)) +>K : Symbol(K, Decl(self-types-keyof.ts, 13, 5)) +>KeyOf : Symbol(KeyOf, Decl(self-types-keyof.ts, 0, 0)) +>T : Symbol(T, Decl(self-types-keyof.ts, 13, 3)) +>t : Symbol(t, Decl(self-types-keyof.ts, 13, 26)) +>T : Symbol(T, Decl(self-types-keyof.ts, 13, 3)) +>k : Symbol(k, Decl(self-types-keyof.ts, 13, 31)) +>K : Symbol(K, Decl(self-types-keyof.ts, 13, 5)) + + T extends { [_ in K]: infer X } ? X : never +>T : Symbol(T, Decl(self-types-keyof.ts, 13, 3)) +>_ : Symbol(_, Decl(self-types-keyof.ts, 14, 17)) +>K : Symbol(K, Decl(self-types-keyof.ts, 13, 5)) +>X : Symbol(X, Decl(self-types-keyof.ts, 14, 31)) +>X : Symbol(X, Decl(self-types-keyof.ts, 14, 31)) + +let t3: number = get({ a: 10 }, "a") +>t3 : Symbol(t3, Decl(self-types-keyof.ts, 16, 3)) +>get : Symbol(get, Decl(self-types-keyof.ts, 12, 13)) +>a : Symbol(a, Decl(self-types-keyof.ts, 16, 22)) + +let t4 = get({ a: 10 }, "b") +>t4 : Symbol(t4, Decl(self-types-keyof.ts, 17, 3)) +>get : Symbol(get, Decl(self-types-keyof.ts, 12, 13)) +>a : Symbol(a, Decl(self-types-keyof.ts, 17, 14)) + +export {} + diff --git a/tests/baselines/reference/self-types-keyof.types b/tests/baselines/reference/self-types-keyof.types new file mode 100644 index 0000000000000..da8047e041ec4 --- /dev/null +++ b/tests/baselines/reference/self-types-keyof.types @@ -0,0 +1,51 @@ +=== tests/cases/compiler/self-types-keyof.ts === +// Implementing index types without index types + +type KeyOf = +>KeyOf : KeyOf + + self extends string | number | symbol + ? T extends { [_ in self]: unknown } + ? self + : Never<`Type '${Print}' can't be used to index type '${Print}'`> + : string | number | symbol + +let t0: KeyOf<{ a: number }> = "a" +>t0 : KeyOf<{ a: number; }> +>a : number +>"a" : "a" + +let t1: KeyOf<{ a: number }> = "b" +>t1 : KeyOf<{ a: number; }> +>a : number +>"b" : "b" + +declare const get: +>get : >(t: T, k: K) => T extends { [_ in K]: infer X; } ? X : never + + >(t: T, k: K) => +>t : T +>k : K + + T extends { [_ in K]: infer X } ? X : never + +let t3: number = get({ a: 10 }, "a") +>t3 : number +>get({ a: 10 }, "a") : number +>get : >(t: T, k: K) => T extends { [_ in K]: infer X; } ? X : never +>{ a: 10 } : { a: number; } +>a : number +>10 : 10 +>"a" : "a" + +let t4 = get({ a: 10 }, "b") +>t4 : { a: number; } extends { [_ in KeyOf<{ a: number; }>]: infer X; } ? X : never +>get({ a: 10 }, "b") : { a: number; } extends { [_ in KeyOf<{ a: number; }>]: infer X; } ? X : never +>get : >(t: T, k: K) => T extends { [_ in K]: infer X; } ? X : never +>{ a: 10 } : { a: number; } +>a : number +>10 : 10 +>"b" : "b" + +export {} + diff --git a/tests/baselines/reference/self-types-mapped.errors.txt b/tests/baselines/reference/self-types-mapped.errors.txt new file mode 100644 index 0000000000000..001ad96349d5b --- /dev/null +++ b/tests/baselines/reference/self-types-mapped.errors.txt @@ -0,0 +1,201 @@ +tests/cases/compiler/self-types-mapped.ts(18,5): error TS18051: Type '{ name: number; age: undefined; }' is not assignable to type '_Partial' + Type '{ name: number; age: undefined; }' is not assignable to type '{ age: number; name: string; }' + Types at property 'name' are incompatible + Type 'number' is not assignable to type 'string' +tests/cases/compiler/self-types-mapped.ts(23,5): error TS18051: Type '{ age: undefined; }' is not assignable to type '_Partial' + Type '{ age: undefined; }' is not assignable to type '{ age: number; name: string; }' + Property 'name' is required in target type but missing in source type +tests/cases/compiler/self-types-mapped.ts(36,5): error TS18051: Type '{ name: number; }' is not assignable to type '_Omit' + Type '{ name: number; }' is not assignable to type '{ name: string; }' + Types at property 'name' are incompatible + Type 'number' is not assignable to type 'string' +tests/cases/compiler/self-types-mapped.ts(40,5): error TS18051: Type '{}' is not assignable to type '_Omit' + Type '{}' is not assignable to type '{ name: string; }' + Property 'name' is required in target type but missing in source type +tests/cases/compiler/self-types-mapped.ts(62,5): error TS18051: Type '{ name: string; age: number; }' is not assignable to type 'FlipValues' + Type '{ name: string; age: number; }' is not assignable to type '{ age: string; name: number; }' + Types at property 'age' are incompatible + Type 'number' is not assignable to type 'string' +tests/cases/compiler/self-types-mapped.ts(72,5): error TS18051: Type '{ name: number; }' is not assignable to type 'FlipValues' + Type '{ name: number; }' is not assignable to type '{ age: string; name: number; }' + Property 'age' is required in target type but missing in source type + + +==== tests/cases/compiler/self-types-mapped.ts (6 errors) ==== + // Implementing mapped types without mapped types + + type User = + { name: string + , age: number + } + + type _Partial = Mapped}>`> + interface Mappers { _Partial: A[K & keyof A] | undefined } + // same as writing + // type _Partial = { [K in keyof T]: T[K] | undefined } + + let t00: _Partial = { + name: "foo", + age: undefined + } + + let t01: _Partial = { + ~~~ +!!! error TS18051: Type '{ name: number; age: undefined; }' is not assignable to type '_Partial' +!!! error TS18051: Type '{ name: number; age: undefined; }' is not assignable to type '{ age: number; name: string; }' +!!! error TS18051: Types at property 'name' are incompatible +!!! error TS18051: Type 'number' is not assignable to type 'string' + name: 0, + age: undefined + } + + let t02: _Partial = { + ~~~ +!!! error TS18051: Type '{ age: undefined; }' is not assignable to type '_Partial' +!!! error TS18051: Type '{ age: undefined; }' is not assignable to type '{ age: number; name: string; }' +!!! error TS18051: Property 'name' is required in target type but missing in source type + age: undefined + } + + type _Omit = Mapped, "_Omit", T, `_Omit<${Print}, ${Print}>`> + interface Mappers { _Omit: A[K & keyof A] } + // same as writing + // type _Omit = { [K in Exclude]: T[K] } + + let t10: _Omit = { + name: "foo" + } + + let t11: _Omit = { + ~~~ +!!! error TS18051: Type '{ name: number; }' is not assignable to type '_Omit' +!!! error TS18051: Type '{ name: number; }' is not assignable to type '{ name: string; }' +!!! error TS18051: Types at property 'name' are incompatible +!!! error TS18051: Type 'number' is not assignable to type 'string' + name: 0 + } + + let t12: _Omit = { + ~~~ +!!! error TS18051: Type '{}' is not assignable to type '_Omit' +!!! error TS18051: Type '{}' is not assignable to type '{ name: string; }' +!!! error TS18051: Property 'name' is required in target type but missing in source type + } + + type FlipValues = + Mapped}, ${Print}, ${Print}>`> + interface Mappers + { FlipValues: + A extends [infer T, infer K1, infer K2] + ? K extends K1 ? T[K2 & keyof T] : + K extends K2 ? T[K1 & keyof T] : + T[K & keyof T] + : never + } + // same as writing + // type FlipValues = + // { [K in keyof T]: + // K extends K1 ? T[K2] : + // K extends K2 ? T[K1] : + // T[K] + // } + + + let t30: FlipValues = { + ~~~ +!!! error TS18051: Type '{ name: string; age: number; }' is not assignable to type 'FlipValues' +!!! error TS18051: Type '{ name: string; age: number; }' is not assignable to type '{ age: string; name: number; }' +!!! error TS18051: Types at property 'age' are incompatible +!!! error TS18051: Type 'number' is not assignable to type 'string' + name: "foo", + age: 0 + } + + let t31: FlipValues = { + name: 0, + age: "foo" + } + + let t32: FlipValues = { + ~~~ +!!! error TS18051: Type '{ name: number; }' is not assignable to type 'FlipValues' +!!! error TS18051: Type '{ name: number; }' is not assignable to type '{ age: string; name: number; }' +!!! error TS18051: Property 'age' is required in target type but missing in source type + name: 0 + } + + /** + * @param K key of new type + * @param F mapper identifier + * @param A extra argument to mapper + * @param N name of new type + */ + type Mapped = + MappedError extends infer E extends string | string[] + ? [E] extends [never] ? self : Never + : never + + type MappedError = + UShift< + K extends unknown + ? K extends keyof Self + ? Get, F> extends infer Fka // F + ? Self[K] extends Fka + ? never + : [ `Type '${Print}' is not assignable to type '${N & string}'` + , `Type '${Print}' is not assignable to type '${PrintMapped}'` + , `Types at property '${PrintKey}' are incompatible` + , `Type '${Print}' is not assignable to type '${Print}'` + ] + : never + : [ `Type '${Print}' is not assignable to type '${N & string}'` + , `Type '${Print}' is not assignable to type '${PrintMapped}'` + , `Property '${PrintKey}' is required in target type but missing in source type` + ] + : never + > + + interface Mappers {} + + type PrintMapped = + `{ ${Join< + K extends unknown + ? `${PrintKey}: ${Print, F>>};` + : never, + " " + >} }` + + + type Join = + UIsUnit extends true ? `${T}` : + `${Cast, string | number>}${D}${Join, D>}` + + type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + + type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + + type UShifted = + Exclude> + + type UIsUnit = + [UShifted] extends [never] ? true : false + + type Cast = + T extends U ? T : U + + type PrintKey = + K extends symbol ? Print : + K extends string ? K : + K extends number ? K : + never + + type Get = + K extends keyof T ? T[K] : never + + export {} \ No newline at end of file diff --git a/tests/baselines/reference/self-types-mapped.js b/tests/baselines/reference/self-types-mapped.js new file mode 100644 index 0000000000000..a19680e13338f --- /dev/null +++ b/tests/baselines/reference/self-types-mapped.js @@ -0,0 +1,196 @@ +//// [self-types-mapped.ts] +// Implementing mapped types without mapped types + +type User = + { name: string + , age: number + } + +type _Partial = Mapped}>`> +interface Mappers { _Partial: A[K & keyof A] | undefined } +// same as writing +// type _Partial = { [K in keyof T]: T[K] | undefined } + +let t00: _Partial = { + name: "foo", + age: undefined +} + +let t01: _Partial = { + name: 0, + age: undefined +} + +let t02: _Partial = { + age: undefined +} + +type _Omit = Mapped, "_Omit", T, `_Omit<${Print}, ${Print}>`> +interface Mappers { _Omit: A[K & keyof A] } +// same as writing +// type _Omit = { [K in Exclude]: T[K] } + +let t10: _Omit = { + name: "foo" +} + +let t11: _Omit = { + name: 0 +} + +let t12: _Omit = { +} + +type FlipValues = + Mapped}, ${Print}, ${Print}>`> +interface Mappers + { FlipValues: + A extends [infer T, infer K1, infer K2] + ? K extends K1 ? T[K2 & keyof T] : + K extends K2 ? T[K1 & keyof T] : + T[K & keyof T] + : never + } +// same as writing +// type FlipValues = +// { [K in keyof T]: +// K extends K1 ? T[K2] : +// K extends K2 ? T[K1] : +// T[K] +// } + + +let t30: FlipValues = { + name: "foo", + age: 0 +} + +let t31: FlipValues = { + name: 0, + age: "foo" +} + +let t32: FlipValues = { + name: 0 +} + +/** + * @param K key of new type + * @param F mapper identifier + * @param A extra argument to mapper + * @param N name of new type + */ +type Mapped = + MappedError extends infer E extends string | string[] + ? [E] extends [never] ? self : Never + : never + +type MappedError = + UShift< + K extends unknown + ? K extends keyof Self + ? Get, F> extends infer Fka // F + ? Self[K] extends Fka + ? never + : [ `Type '${Print}' is not assignable to type '${N & string}'` + , `Type '${Print}' is not assignable to type '${PrintMapped}'` + , `Types at property '${PrintKey}' are incompatible` + , `Type '${Print}' is not assignable to type '${Print}'` + ] + : never + : [ `Type '${Print}' is not assignable to type '${N & string}'` + , `Type '${Print}' is not assignable to type '${PrintMapped}'` + , `Property '${PrintKey}' is required in target type but missing in source type` + ] + : never + > + +interface Mappers {} + +type PrintMapped = + `{ ${Join< + K extends unknown + ? `${PrintKey}: ${Print, F>>};` + : never, + " " + >} }` + + +type Join = + UIsUnit extends true ? `${T}` : + `${Cast, string | number>}${D}${Join, D>}` + +type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + +type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + +type UShifted = + Exclude> + +type UIsUnit = + [UShifted] extends [never] ? true : false + +type Cast = + T extends U ? T : U + +type PrintKey = + K extends symbol ? Print : + K extends string ? K : + K extends number ? K : + never + +type Get = + K extends keyof T ? T[K] : never + +export {} + +//// [self-types-mapped.js] +"use strict"; +// Implementing mapped types without mapped types +Object.defineProperty(exports, "__esModule", { value: true }); +// same as writing +// type _Partial = { [K in keyof T]: T[K] | undefined } +var t00 = { + name: "foo", + age: undefined +}; +var t01 = { + name: 0, + age: undefined +}; +var t02 = { + age: undefined +}; +// same as writing +// type _Omit = { [K in Exclude]: T[K] } +var t10 = { + name: "foo" +}; +var t11 = { + name: 0 +}; +var t12 = {}; +// same as writing +// type FlipValues = +// { [K in keyof T]: +// K extends K1 ? T[K2] : +// K extends K2 ? T[K1] : +// T[K] +// } +var t30 = { + name: "foo", + age: 0 +}; +var t31 = { + name: 0, + age: "foo" +}; +var t32 = { + name: 0 +}; diff --git a/tests/baselines/reference/self-types-mapped.symbols b/tests/baselines/reference/self-types-mapped.symbols new file mode 100644 index 0000000000000..a81901751c917 --- /dev/null +++ b/tests/baselines/reference/self-types-mapped.symbols @@ -0,0 +1,472 @@ +=== tests/cases/compiler/self-types-mapped.ts === +// Implementing mapped types without mapped types + +type User = +>User : Symbol(User, Decl(self-types-mapped.ts, 0, 0)) + + { name: string +>name : Symbol(name, Decl(self-types-mapped.ts, 3, 3)) + + , age: number +>age : Symbol(age, Decl(self-types-mapped.ts, 4, 3)) + } + +type _Partial = Mapped}>`> +>_Partial : Symbol(_Partial, Decl(self-types-mapped.ts, 5, 3)) +>T : Symbol(T, Decl(self-types-mapped.ts, 7, 14)) +>Mapped : Symbol(Mapped, Decl(self-types-mapped.ts, 73, 1)) +>T : Symbol(T, Decl(self-types-mapped.ts, 7, 14)) +>T : Symbol(T, Decl(self-types-mapped.ts, 7, 14)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-mapped.ts, 7, 14)) + +interface Mappers { _Partial: A[K & keyof A] | undefined } +>Mappers : Symbol(Mappers, Decl(self-types-mapped.ts, 7, 74), Decl(self-types-mapped.ts, 26, 93), Decl(self-types-mapped.ts, 43, 99), Decl(self-types-mapped.ts, 104, 3)) +>K : Symbol(K, Decl(self-types-mapped.ts, 8, 18), Decl(self-types-mapped.ts, 27, 18), Decl(self-types-mapped.ts, 44, 18), Decl(self-types-mapped.ts, 106, 18)) +>A : Symbol(A, Decl(self-types-mapped.ts, 8, 20), Decl(self-types-mapped.ts, 27, 20), Decl(self-types-mapped.ts, 44, 20), Decl(self-types-mapped.ts, 106, 20)) +>_Partial : Symbol(Mappers._Partial, Decl(self-types-mapped.ts, 8, 25)) +>A : Symbol(A, Decl(self-types-mapped.ts, 8, 20), Decl(self-types-mapped.ts, 27, 20), Decl(self-types-mapped.ts, 44, 20), Decl(self-types-mapped.ts, 106, 20)) +>K : Symbol(K, Decl(self-types-mapped.ts, 8, 18), Decl(self-types-mapped.ts, 27, 18), Decl(self-types-mapped.ts, 44, 18), Decl(self-types-mapped.ts, 106, 18)) +>A : Symbol(A, Decl(self-types-mapped.ts, 8, 20), Decl(self-types-mapped.ts, 27, 20), Decl(self-types-mapped.ts, 44, 20), Decl(self-types-mapped.ts, 106, 20)) + +// same as writing +// type _Partial = { [K in keyof T]: T[K] | undefined } + +let t00: _Partial = { +>t00 : Symbol(t00, Decl(self-types-mapped.ts, 12, 3)) +>_Partial : Symbol(_Partial, Decl(self-types-mapped.ts, 5, 3)) +>User : Symbol(User, Decl(self-types-mapped.ts, 0, 0)) + + name: "foo", +>name : Symbol(name, Decl(self-types-mapped.ts, 12, 27)) + + age: undefined +>age : Symbol(age, Decl(self-types-mapped.ts, 13, 14)) +>undefined : Symbol(undefined) +} + +let t01: _Partial = { +>t01 : Symbol(t01, Decl(self-types-mapped.ts, 17, 3)) +>_Partial : Symbol(_Partial, Decl(self-types-mapped.ts, 5, 3)) +>User : Symbol(User, Decl(self-types-mapped.ts, 0, 0)) + + name: 0, +>name : Symbol(name, Decl(self-types-mapped.ts, 17, 27)) + + age: undefined +>age : Symbol(age, Decl(self-types-mapped.ts, 18, 10)) +>undefined : Symbol(undefined) +} + +let t02: _Partial = { +>t02 : Symbol(t02, Decl(self-types-mapped.ts, 22, 3)) +>_Partial : Symbol(_Partial, Decl(self-types-mapped.ts, 5, 3)) +>User : Symbol(User, Decl(self-types-mapped.ts, 0, 0)) + + age: undefined +>age : Symbol(age, Decl(self-types-mapped.ts, 22, 27)) +>undefined : Symbol(undefined) +} + +type _Omit = Mapped, "_Omit", T, `_Omit<${Print}, ${Print}>`> +>_Omit : Symbol(_Omit, Decl(self-types-mapped.ts, 24, 1)) +>T : Symbol(T, Decl(self-types-mapped.ts, 26, 11)) +>K : Symbol(K, Decl(self-types-mapped.ts, 26, 13)) +>Mapped : Symbol(Mapped, Decl(self-types-mapped.ts, 73, 1)) +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-mapped.ts, 26, 11)) +>K : Symbol(K, Decl(self-types-mapped.ts, 26, 13)) +>T : Symbol(T, Decl(self-types-mapped.ts, 26, 11)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-mapped.ts, 26, 11)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(self-types-mapped.ts, 26, 13)) + +interface Mappers { _Omit: A[K & keyof A] } +>Mappers : Symbol(Mappers, Decl(self-types-mapped.ts, 7, 74), Decl(self-types-mapped.ts, 26, 93), Decl(self-types-mapped.ts, 43, 99), Decl(self-types-mapped.ts, 104, 3)) +>K : Symbol(K, Decl(self-types-mapped.ts, 8, 18), Decl(self-types-mapped.ts, 27, 18), Decl(self-types-mapped.ts, 44, 18), Decl(self-types-mapped.ts, 106, 18)) +>A : Symbol(A, Decl(self-types-mapped.ts, 8, 20), Decl(self-types-mapped.ts, 27, 20), Decl(self-types-mapped.ts, 44, 20), Decl(self-types-mapped.ts, 106, 20)) +>_Omit : Symbol(Mappers._Omit, Decl(self-types-mapped.ts, 27, 25)) +>A : Symbol(A, Decl(self-types-mapped.ts, 8, 20), Decl(self-types-mapped.ts, 27, 20), Decl(self-types-mapped.ts, 44, 20), Decl(self-types-mapped.ts, 106, 20)) +>K : Symbol(K, Decl(self-types-mapped.ts, 8, 18), Decl(self-types-mapped.ts, 27, 18), Decl(self-types-mapped.ts, 44, 18), Decl(self-types-mapped.ts, 106, 18)) +>A : Symbol(A, Decl(self-types-mapped.ts, 8, 20), Decl(self-types-mapped.ts, 27, 20), Decl(self-types-mapped.ts, 44, 20), Decl(self-types-mapped.ts, 106, 20)) + +// same as writing +// type _Omit = { [K in Exclude]: T[K] } + +let t10: _Omit = { +>t10 : Symbol(t10, Decl(self-types-mapped.ts, 31, 3)) +>_Omit : Symbol(_Omit, Decl(self-types-mapped.ts, 24, 1)) +>User : Symbol(User, Decl(self-types-mapped.ts, 0, 0)) + + name: "foo" +>name : Symbol(name, Decl(self-types-mapped.ts, 31, 31)) +} + +let t11: _Omit = { +>t11 : Symbol(t11, Decl(self-types-mapped.ts, 35, 3)) +>_Omit : Symbol(_Omit, Decl(self-types-mapped.ts, 24, 1)) +>User : Symbol(User, Decl(self-types-mapped.ts, 0, 0)) + + name: 0 +>name : Symbol(name, Decl(self-types-mapped.ts, 35, 31)) +} + +let t12: _Omit = { +>t12 : Symbol(t12, Decl(self-types-mapped.ts, 39, 3)) +>_Omit : Symbol(_Omit, Decl(self-types-mapped.ts, 24, 1)) +>User : Symbol(User, Decl(self-types-mapped.ts, 0, 0)) +} + +type FlipValues = +>FlipValues : Symbol(FlipValues, Decl(self-types-mapped.ts, 40, 1)) +>T : Symbol(T, Decl(self-types-mapped.ts, 42, 16)) +>K1 : Symbol(K1, Decl(self-types-mapped.ts, 42, 18)) +>T : Symbol(T, Decl(self-types-mapped.ts, 42, 16)) +>K2 : Symbol(K2, Decl(self-types-mapped.ts, 42, 38)) +>T : Symbol(T, Decl(self-types-mapped.ts, 42, 16)) + + Mapped}, ${Print}, ${Print}>`> +>Mapped : Symbol(Mapped, Decl(self-types-mapped.ts, 73, 1)) +>T : Symbol(T, Decl(self-types-mapped.ts, 42, 16)) +>T : Symbol(T, Decl(self-types-mapped.ts, 42, 16)) +>K1 : Symbol(K1, Decl(self-types-mapped.ts, 42, 18)) +>K2 : Symbol(K2, Decl(self-types-mapped.ts, 42, 38)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-mapped.ts, 42, 16)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>K1 : Symbol(K1, Decl(self-types-mapped.ts, 42, 18)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>K2 : Symbol(K2, Decl(self-types-mapped.ts, 42, 38)) + +interface Mappers +>Mappers : Symbol(Mappers, Decl(self-types-mapped.ts, 7, 74), Decl(self-types-mapped.ts, 26, 93), Decl(self-types-mapped.ts, 43, 99), Decl(self-types-mapped.ts, 104, 3)) +>K : Symbol(K, Decl(self-types-mapped.ts, 8, 18), Decl(self-types-mapped.ts, 27, 18), Decl(self-types-mapped.ts, 44, 18), Decl(self-types-mapped.ts, 106, 18)) +>A : Symbol(A, Decl(self-types-mapped.ts, 8, 20), Decl(self-types-mapped.ts, 27, 20), Decl(self-types-mapped.ts, 44, 20), Decl(self-types-mapped.ts, 106, 20)) + + { FlipValues: +>FlipValues : Symbol(Mappers.FlipValues, Decl(self-types-mapped.ts, 45, 3)) + + A extends [infer T, infer K1, infer K2] +>A : Symbol(A, Decl(self-types-mapped.ts, 8, 20), Decl(self-types-mapped.ts, 27, 20), Decl(self-types-mapped.ts, 44, 20), Decl(self-types-mapped.ts, 106, 20)) +>T : Symbol(T, Decl(self-types-mapped.ts, 46, 22)) +>K1 : Symbol(K1, Decl(self-types-mapped.ts, 46, 31)) +>K2 : Symbol(K2, Decl(self-types-mapped.ts, 46, 41)) + + ? K extends K1 ? T[K2 & keyof T] : +>K : Symbol(K, Decl(self-types-mapped.ts, 8, 18), Decl(self-types-mapped.ts, 27, 18), Decl(self-types-mapped.ts, 44, 18), Decl(self-types-mapped.ts, 106, 18)) +>K1 : Symbol(K1, Decl(self-types-mapped.ts, 46, 31)) +>T : Symbol(T, Decl(self-types-mapped.ts, 46, 22)) +>K2 : Symbol(K2, Decl(self-types-mapped.ts, 46, 41)) +>T : Symbol(T, Decl(self-types-mapped.ts, 46, 22)) + + K extends K2 ? T[K1 & keyof T] : +>K : Symbol(K, Decl(self-types-mapped.ts, 8, 18), Decl(self-types-mapped.ts, 27, 18), Decl(self-types-mapped.ts, 44, 18), Decl(self-types-mapped.ts, 106, 18)) +>K2 : Symbol(K2, Decl(self-types-mapped.ts, 46, 41)) +>T : Symbol(T, Decl(self-types-mapped.ts, 46, 22)) +>K1 : Symbol(K1, Decl(self-types-mapped.ts, 46, 31)) +>T : Symbol(T, Decl(self-types-mapped.ts, 46, 22)) + + T[K & keyof T] +>T : Symbol(T, Decl(self-types-mapped.ts, 46, 22)) +>K : Symbol(K, Decl(self-types-mapped.ts, 8, 18), Decl(self-types-mapped.ts, 27, 18), Decl(self-types-mapped.ts, 44, 18), Decl(self-types-mapped.ts, 106, 18)) +>T : Symbol(T, Decl(self-types-mapped.ts, 46, 22)) + + : never + } +// same as writing +// type FlipValues = +// { [K in keyof T]: +// K extends K1 ? T[K2] : +// K extends K2 ? T[K1] : +// T[K] +// } + + +let t30: FlipValues = { +>t30 : Symbol(t30, Decl(self-types-mapped.ts, 61, 3)) +>FlipValues : Symbol(FlipValues, Decl(self-types-mapped.ts, 40, 1)) +>User : Symbol(User, Decl(self-types-mapped.ts, 0, 0)) + + name: "foo", +>name : Symbol(name, Decl(self-types-mapped.ts, 61, 44)) + + age: 0 +>age : Symbol(age, Decl(self-types-mapped.ts, 62, 14)) +} + +let t31: FlipValues = { +>t31 : Symbol(t31, Decl(self-types-mapped.ts, 66, 3)) +>FlipValues : Symbol(FlipValues, Decl(self-types-mapped.ts, 40, 1)) +>User : Symbol(User, Decl(self-types-mapped.ts, 0, 0)) + + name: 0, +>name : Symbol(name, Decl(self-types-mapped.ts, 66, 44)) + + age: "foo" +>age : Symbol(age, Decl(self-types-mapped.ts, 67, 10)) +} + +let t32: FlipValues = { +>t32 : Symbol(t32, Decl(self-types-mapped.ts, 71, 3)) +>FlipValues : Symbol(FlipValues, Decl(self-types-mapped.ts, 40, 1)) +>User : Symbol(User, Decl(self-types-mapped.ts, 0, 0)) + + name: 0 +>name : Symbol(name, Decl(self-types-mapped.ts, 71, 44)) +} + +/** + * @param K key of new type + * @param F mapper identifier + * @param A extra argument to mapper + * @param N name of new type + */ +type Mapped = +>Mapped : Symbol(Mapped, Decl(self-types-mapped.ts, 73, 1)) +>K : Symbol(K, Decl(self-types-mapped.ts, 81, 12)) +>F : Symbol(F, Decl(self-types-mapped.ts, 81, 14)) +>A : Symbol(A, Decl(self-types-mapped.ts, 81, 17)) +>N : Symbol(N, Decl(self-types-mapped.ts, 81, 20)) + + MappedError extends infer E extends string | string[] +>MappedError : Symbol(MappedError, Decl(self-types-mapped.ts, 84, 11)) +>K : Symbol(K, Decl(self-types-mapped.ts, 81, 12)) +>F : Symbol(F, Decl(self-types-mapped.ts, 81, 14)) +>A : Symbol(A, Decl(self-types-mapped.ts, 81, 17)) +>N : Symbol(N, Decl(self-types-mapped.ts, 81, 20)) +>E : Symbol(E, Decl(self-types-mapped.ts, 82, 45)) + + ? [E] extends [never] ? self : Never +>E : Symbol(E, Decl(self-types-mapped.ts, 82, 45)) +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) +>E : Symbol(E, Decl(self-types-mapped.ts, 82, 45)) + + : never + +type MappedError = +>MappedError : Symbol(MappedError, Decl(self-types-mapped.ts, 84, 11)) +>K : Symbol(K, Decl(self-types-mapped.ts, 86, 17)) +>F : Symbol(F, Decl(self-types-mapped.ts, 86, 19)) +>A : Symbol(A, Decl(self-types-mapped.ts, 86, 22)) +>N : Symbol(N, Decl(self-types-mapped.ts, 86, 25)) +>Self : Symbol(Self, Decl(self-types-mapped.ts, 86, 28)) +>KCopy : Symbol(KCopy, Decl(self-types-mapped.ts, 86, 34)) +>K : Symbol(K, Decl(self-types-mapped.ts, 86, 17)) + + UShift< +>UShift : Symbol(UShift, Decl(self-types-mapped.ts, 119, 66)) + + K extends unknown +>K : Symbol(K, Decl(self-types-mapped.ts, 86, 17)) + + ? K extends keyof Self +>K : Symbol(K, Decl(self-types-mapped.ts, 86, 17)) +>Self : Symbol(Self, Decl(self-types-mapped.ts, 86, 28)) + + ? Get, F> extends infer Fka // F +>Get : Symbol(Get, Decl(self-types-mapped.ts, 144, 7)) +>Mappers : Symbol(Mappers, Decl(self-types-mapped.ts, 7, 74), Decl(self-types-mapped.ts, 26, 93), Decl(self-types-mapped.ts, 43, 99), Decl(self-types-mapped.ts, 104, 3)) +>K : Symbol(K, Decl(self-types-mapped.ts, 86, 17)) +>A : Symbol(A, Decl(self-types-mapped.ts, 86, 22)) +>F : Symbol(F, Decl(self-types-mapped.ts, 86, 19)) +>Fka : Symbol(Fka, Decl(self-types-mapped.ts, 90, 47)) + + ? Self[K] extends Fka +>Self : Symbol(Self, Decl(self-types-mapped.ts, 86, 28)) +>K : Symbol(K, Decl(self-types-mapped.ts, 86, 17)) +>Fka : Symbol(Fka, Decl(self-types-mapped.ts, 90, 47)) + + ? never + : [ `Type '${Print}' is not assignable to type '${N & string}'` +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Self : Symbol(Self, Decl(self-types-mapped.ts, 86, 28)) +>N : Symbol(N, Decl(self-types-mapped.ts, 86, 25)) + + , `Type '${Print}' is not assignable to type '${PrintMapped}'` +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Self : Symbol(Self, Decl(self-types-mapped.ts, 86, 28)) +>PrintMapped : Symbol(PrintMapped, Decl(self-types-mapped.ts, 106, 26)) +>KCopy : Symbol(KCopy, Decl(self-types-mapped.ts, 86, 34)) +>F : Symbol(F, Decl(self-types-mapped.ts, 86, 19)) +>A : Symbol(A, Decl(self-types-mapped.ts, 86, 22)) + + , `Types at property '${PrintKey}' are incompatible` +>PrintKey : Symbol(PrintKey, Decl(self-types-mapped.ts, 138, 21)) +>K : Symbol(K, Decl(self-types-mapped.ts, 86, 17)) + + , `Type '${Print}' is not assignable to type '${Print}'` +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Self : Symbol(Self, Decl(self-types-mapped.ts, 86, 28)) +>K : Symbol(K, Decl(self-types-mapped.ts, 86, 17)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Fka : Symbol(Fka, Decl(self-types-mapped.ts, 90, 47)) + + ] + : never + : [ `Type '${Print}' is not assignable to type '${N & string}'` +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Self : Symbol(Self, Decl(self-types-mapped.ts, 86, 28)) +>N : Symbol(N, Decl(self-types-mapped.ts, 86, 25)) + + , `Type '${Print}' is not assignable to type '${PrintMapped}'` +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Self : Symbol(Self, Decl(self-types-mapped.ts, 86, 28)) +>PrintMapped : Symbol(PrintMapped, Decl(self-types-mapped.ts, 106, 26)) +>KCopy : Symbol(KCopy, Decl(self-types-mapped.ts, 86, 34)) +>F : Symbol(F, Decl(self-types-mapped.ts, 86, 19)) +>A : Symbol(A, Decl(self-types-mapped.ts, 86, 22)) + + , `Property '${PrintKey}' is required in target type but missing in source type` +>PrintKey : Symbol(PrintKey, Decl(self-types-mapped.ts, 138, 21)) +>K : Symbol(K, Decl(self-types-mapped.ts, 86, 17)) + + ] + : never + > + +interface Mappers {} +>Mappers : Symbol(Mappers, Decl(self-types-mapped.ts, 7, 74), Decl(self-types-mapped.ts, 26, 93), Decl(self-types-mapped.ts, 43, 99), Decl(self-types-mapped.ts, 104, 3)) +>K : Symbol(K, Decl(self-types-mapped.ts, 8, 18), Decl(self-types-mapped.ts, 27, 18), Decl(self-types-mapped.ts, 44, 18), Decl(self-types-mapped.ts, 106, 18)) +>A : Symbol(A, Decl(self-types-mapped.ts, 8, 20), Decl(self-types-mapped.ts, 27, 20), Decl(self-types-mapped.ts, 44, 20), Decl(self-types-mapped.ts, 106, 20)) + +type PrintMapped = +>PrintMapped : Symbol(PrintMapped, Decl(self-types-mapped.ts, 106, 26)) +>K : Symbol(K, Decl(self-types-mapped.ts, 108, 17)) +>F : Symbol(F, Decl(self-types-mapped.ts, 108, 19)) +>A : Symbol(A, Decl(self-types-mapped.ts, 108, 22)) + + `{ ${Join< +>Join : Symbol(Join, Decl(self-types-mapped.ts, 114, 7)) + + K extends unknown +>K : Symbol(K, Decl(self-types-mapped.ts, 108, 17)) + + ? `${PrintKey}: ${Print, F>>};` +>PrintKey : Symbol(PrintKey, Decl(self-types-mapped.ts, 138, 21)) +>K : Symbol(K, Decl(self-types-mapped.ts, 108, 17)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Get : Symbol(Get, Decl(self-types-mapped.ts, 144, 7)) +>Mappers : Symbol(Mappers, Decl(self-types-mapped.ts, 7, 74), Decl(self-types-mapped.ts, 26, 93), Decl(self-types-mapped.ts, 43, 99), Decl(self-types-mapped.ts, 104, 3)) +>K : Symbol(K, Decl(self-types-mapped.ts, 108, 17)) +>A : Symbol(A, Decl(self-types-mapped.ts, 108, 22)) +>F : Symbol(F, Decl(self-types-mapped.ts, 108, 19)) + + : never, + " " + >} }` + + +type Join = +>Join : Symbol(Join, Decl(self-types-mapped.ts, 114, 7)) +>T : Symbol(T, Decl(self-types-mapped.ts, 117, 10)) +>D : Symbol(D, Decl(self-types-mapped.ts, 117, 27)) + + UIsUnit extends true ? `${T}` : +>UIsUnit : Symbol(UIsUnit, Decl(self-types-mapped.ts, 132, 23)) +>T : Symbol(T, Decl(self-types-mapped.ts, 117, 10)) +>T : Symbol(T, Decl(self-types-mapped.ts, 117, 10)) + + `${Cast, string | number>}${D}${Join, D>}` +>Cast : Symbol(Cast, Decl(self-types-mapped.ts, 135, 46)) +>UShift : Symbol(UShift, Decl(self-types-mapped.ts, 119, 66)) +>T : Symbol(T, Decl(self-types-mapped.ts, 117, 10)) +>D : Symbol(D, Decl(self-types-mapped.ts, 117, 27)) +>Join : Symbol(Join, Decl(self-types-mapped.ts, 114, 7)) +>UShifted : Symbol(UShifted, Decl(self-types-mapped.ts, 129, 11)) +>T : Symbol(T, Decl(self-types-mapped.ts, 117, 10)) +>D : Symbol(D, Decl(self-types-mapped.ts, 117, 27)) + +type UShift = +>UShift : Symbol(UShift, Decl(self-types-mapped.ts, 119, 66)) +>U : Symbol(U, Decl(self-types-mapped.ts, 121, 12)) + + UToIntersection void : never> extends (_: infer H) => void +>UToIntersection : Symbol(UToIntersection, Decl(self-types-mapped.ts, 124, 11)) +>U : Symbol(U, Decl(self-types-mapped.ts, 121, 12)) +>x : Symbol(x, Decl(self-types-mapped.ts, 122, 39)) +>U : Symbol(U, Decl(self-types-mapped.ts, 121, 12)) +>_ : Symbol(_, Decl(self-types-mapped.ts, 122, 71)) +>H : Symbol(H, Decl(self-types-mapped.ts, 122, 79)) + + ? H +>H : Symbol(H, Decl(self-types-mapped.ts, 122, 79)) + + : never + +type UToIntersection = +>UToIntersection : Symbol(UToIntersection, Decl(self-types-mapped.ts, 124, 11)) +>T : Symbol(T, Decl(self-types-mapped.ts, 126, 21)) + + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) +>T : Symbol(T, Decl(self-types-mapped.ts, 126, 21)) +>_ : Symbol(_, Decl(self-types-mapped.ts, 127, 24)) +>T : Symbol(T, Decl(self-types-mapped.ts, 126, 21)) +>_ : Symbol(_, Decl(self-types-mapped.ts, 127, 57)) +>I : Symbol(I, Decl(self-types-mapped.ts, 127, 65)) + + ? I +>I : Symbol(I, Decl(self-types-mapped.ts, 127, 65)) + + : never + +type UShifted = +>UShifted : Symbol(UShifted, Decl(self-types-mapped.ts, 129, 11)) +>U : Symbol(U, Decl(self-types-mapped.ts, 131, 14)) + + Exclude> +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(self-types-mapped.ts, 131, 14)) +>UShift : Symbol(UShift, Decl(self-types-mapped.ts, 119, 66)) +>U : Symbol(U, Decl(self-types-mapped.ts, 131, 14)) + +type UIsUnit = +>UIsUnit : Symbol(UIsUnit, Decl(self-types-mapped.ts, 132, 23)) +>U : Symbol(U, Decl(self-types-mapped.ts, 134, 13)) + + [UShifted] extends [never] ? true : false +>UShifted : Symbol(UShifted, Decl(self-types-mapped.ts, 129, 11)) +>U : Symbol(U, Decl(self-types-mapped.ts, 134, 13)) + +type Cast = +>Cast : Symbol(Cast, Decl(self-types-mapped.ts, 135, 46)) +>T : Symbol(T, Decl(self-types-mapped.ts, 137, 10)) +>U : Symbol(U, Decl(self-types-mapped.ts, 137, 12)) + + T extends U ? T : U +>T : Symbol(T, Decl(self-types-mapped.ts, 137, 10)) +>U : Symbol(U, Decl(self-types-mapped.ts, 137, 12)) +>T : Symbol(T, Decl(self-types-mapped.ts, 137, 10)) +>U : Symbol(U, Decl(self-types-mapped.ts, 137, 12)) + +type PrintKey = +>PrintKey : Symbol(PrintKey, Decl(self-types-mapped.ts, 138, 21)) +>K : Symbol(K, Decl(self-types-mapped.ts, 140, 14)) + + K extends symbol ? Print : +>K : Symbol(K, Decl(self-types-mapped.ts, 140, 14)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>K : Symbol(K, Decl(self-types-mapped.ts, 140, 14)) + + K extends string ? K : +>K : Symbol(K, Decl(self-types-mapped.ts, 140, 14)) +>K : Symbol(K, Decl(self-types-mapped.ts, 140, 14)) + + K extends number ? K : +>K : Symbol(K, Decl(self-types-mapped.ts, 140, 14)) +>K : Symbol(K, Decl(self-types-mapped.ts, 140, 14)) + + never + +type Get = +>Get : Symbol(Get, Decl(self-types-mapped.ts, 144, 7)) +>T : Symbol(T, Decl(self-types-mapped.ts, 146, 9)) +>K : Symbol(K, Decl(self-types-mapped.ts, 146, 11)) + + K extends keyof T ? T[K] : never +>K : Symbol(K, Decl(self-types-mapped.ts, 146, 11)) +>T : Symbol(T, Decl(self-types-mapped.ts, 146, 9)) +>T : Symbol(T, Decl(self-types-mapped.ts, 146, 9)) +>K : Symbol(K, Decl(self-types-mapped.ts, 146, 11)) + +export {} diff --git a/tests/baselines/reference/self-types-mapped.types b/tests/baselines/reference/self-types-mapped.types new file mode 100644 index 0000000000000..780f1b87053fd --- /dev/null +++ b/tests/baselines/reference/self-types-mapped.types @@ -0,0 +1,254 @@ +=== tests/cases/compiler/self-types-mapped.ts === +// Implementing mapped types without mapped types + +type User = +>User : { name: string; age: number; } + + { name: string +>name : string + + , age: number +>age : number + } + +type _Partial = Mapped}>`> +>_Partial : Mapped"> + +interface Mappers { _Partial: A[K & keyof A] | undefined } +>_Partial : A[K & keyof A] + +// same as writing +// type _Partial = { [K in keyof T]: T[K] | undefined } + +let t00: _Partial = { +>t00 : Mapped"> +>{ name: "foo", age: undefined} : { name: string; age: undefined; } + + name: "foo", +>name : string +>"foo" : "foo" + + age: undefined +>age : undefined +>undefined : undefined +} + +let t01: _Partial = { +>t01 : Mapped"> +>{ name: 0, age: undefined} : { name: number; age: undefined; } + + name: 0, +>name : number +>0 : 0 + + age: undefined +>age : undefined +>undefined : undefined +} + +let t02: _Partial = { +>t02 : Mapped"> +>{ age: undefined} : { age: undefined; } + + age: undefined +>age : undefined +>undefined : undefined +} + +type _Omit = Mapped, "_Omit", T, `_Omit<${Print}, ${Print}>`> +>_Omit : Mapped, "_Omit", T, "_Omit"> + +interface Mappers { _Omit: A[K & keyof A] } +>_Omit : A[K & keyof A] + +// same as writing +// type _Omit = { [K in Exclude]: T[K] } + +let t10: _Omit = { +>t10 : Mapped<"name", "_Omit", User, "_Omit"> +>{ name: "foo"} : { name: string; } + + name: "foo" +>name : string +>"foo" : "foo" +} + +let t11: _Omit = { +>t11 : Mapped<"name", "_Omit", User, "_Omit"> +>{ name: 0} : { name: number; } + + name: 0 +>name : number +>0 : 0 +} + +let t12: _Omit = { +>t12 : Mapped<"name", "_Omit", User, "_Omit"> +>{} : {} +} + +type FlipValues = +>FlipValues : Mapped"> + + Mapped}, ${Print}, ${Print}>`> +interface Mappers + { FlipValues: +>FlipValues : A extends [infer T, infer K1, infer K2] ? K extends K1 ? T[K2 & keyof T] : K extends K2 ? T[K1 & keyof T] : T[K & keyof T] : never + + A extends [infer T, infer K1, infer K2] + ? K extends K1 ? T[K2 & keyof T] : + K extends K2 ? T[K1 & keyof T] : + T[K & keyof T] + : never + } +// same as writing +// type FlipValues = +// { [K in keyof T]: +// K extends K1 ? T[K2] : +// K extends K2 ? T[K1] : +// T[K] +// } + + +let t30: FlipValues = { +>t30 : Mapped"> +>{ name: "foo", age: 0} : { name: string; age: number; } + + name: "foo", +>name : string +>"foo" : "foo" + + age: 0 +>age : number +>0 : 0 +} + +let t31: FlipValues = { +>t31 : Mapped"> +>{ name: 0, age: "foo"} : { name: number; age: string; } + + name: 0, +>name : number +>0 : 0 + + age: "foo" +>age : string +>"foo" : "foo" +} + +let t32: FlipValues = { +>t32 : Mapped"> +>{ name: 0} : { name: number; } + + name: 0 +>name : number +>0 : 0 +} + +/** + * @param K key of new type + * @param F mapper identifier + * @param A extra argument to mapper + * @param N name of new type + */ +type Mapped = +>Mapped : Mapped + + MappedError extends infer E extends string | string[] + ? [E] extends [never] ? self : Never + : never + +type MappedError = +>MappedError : MappedError + + UShift< + K extends unknown + ? K extends keyof Self + ? Get, F> extends infer Fka // F + ? Self[K] extends Fka + ? never + : [ `Type '${Print}' is not assignable to type '${N & string}'` + , `Type '${Print}' is not assignable to type '${PrintMapped}'` + , `Types at property '${PrintKey}' are incompatible` + , `Type '${Print}' is not assignable to type '${Print}'` + ] + : never + : [ `Type '${Print}' is not assignable to type '${N & string}'` + , `Type '${Print}' is not assignable to type '${PrintMapped}'` + , `Property '${PrintKey}' is required in target type but missing in source type` + ] + : never + > + +interface Mappers {} + +type PrintMapped = +>PrintMapped : `{ ${Join}: Get, F>;` : never, " ">} }` + + `{ ${Join< + K extends unknown + ? `${PrintKey}: ${Print, F>>};` + : never, + " " + >} }` + + +type Join = +>Join : Join + + UIsUnit extends true ? `${T}` : +>true : true + + `${Cast, string | number>}${D}${Join, D>}` + +type UShift = +>UShift : UShift + + UToIntersection void : never> extends (_: infer H) => void +>x : U +>_ : H + + ? H + : never + +type UToIntersection = +>UToIntersection : UToIntersection + + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) +>_ : T +>_ : I + + ? I + : never + +type UShifted = +>UShifted : UShifted + + Exclude> + +type UIsUnit = +>UIsUnit : UIsUnit + + [UShifted] extends [never] ? true : false +>true : true +>false : false + +type Cast = +>Cast : Cast + + T extends U ? T : U + +type PrintKey = +>PrintKey : PrintKey + + K extends symbol ? Print : + K extends string ? K : + K extends number ? K : + never + +type Get = +>Get : Get + + K extends keyof T ? T[K] : never + +export {} diff --git a/tests/baselines/reference/self-types-non-zero-number.errors.txt b/tests/baselines/reference/self-types-non-zero-number.errors.txt new file mode 100644 index 0000000000000..707c8221a0d80 --- /dev/null +++ b/tests/baselines/reference/self-types-non-zero-number.errors.txt @@ -0,0 +1,23 @@ +tests/cases/compiler/self-types-non-zero-number.ts(10,11): error TS18051: Type '0' is not assignable to type 'NonZeroNumber' +tests/cases/compiler/self-types-non-zero-number.ts(12,11): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + + +==== tests/cases/compiler/self-types-non-zero-number.ts (2 errors) ==== + type NonZeroNumber = + self extends number + ? self extends 0 + ? Never<`Type '${Print}' is not assignable to type 'NonZeroNumber'`> + : self + : number + + const divide = (a: number, b: NonZeroNumber) => (a / (b as number)) as NonZeroNumber + + divide(1, 0) + ~ +!!! error TS18051: Type '0' is not assignable to type 'NonZeroNumber' + divide(1, 1) + divide(1, "x") + ~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'. + + export {} \ No newline at end of file diff --git a/tests/baselines/reference/self-types-non-zero-number.js b/tests/baselines/reference/self-types-non-zero-number.js new file mode 100644 index 0000000000000..a6c65890532e6 --- /dev/null +++ b/tests/baselines/reference/self-types-non-zero-number.js @@ -0,0 +1,23 @@ +//// [self-types-non-zero-number.ts] +type NonZeroNumber = + self extends number + ? self extends 0 + ? Never<`Type '${Print}' is not assignable to type 'NonZeroNumber'`> + : self + : number + +const divide = (a: number, b: NonZeroNumber) => (a / (b as number)) as NonZeroNumber + +divide(1, 0) +divide(1, 1) +divide(1, "x") + +export {} + +//// [self-types-non-zero-number.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var divide = function (a, b) { return (a / b); }; +divide(1, 0); +divide(1, 1); +divide(1, "x"); diff --git a/tests/baselines/reference/self-types-non-zero-number.symbols b/tests/baselines/reference/self-types-non-zero-number.symbols new file mode 100644 index 0000000000000..5e687c8aefaf6 --- /dev/null +++ b/tests/baselines/reference/self-types-non-zero-number.symbols @@ -0,0 +1,32 @@ +=== tests/cases/compiler/self-types-non-zero-number.ts === +type NonZeroNumber = +>NonZeroNumber : Symbol(NonZeroNumber, Decl(self-types-non-zero-number.ts, 0, 0)) + + self extends number + ? self extends 0 + ? Never<`Type '${Print}' is not assignable to type 'NonZeroNumber'`> +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) + + : self + : number + +const divide = (a: number, b: NonZeroNumber) => (a / (b as number)) as NonZeroNumber +>divide : Symbol(divide, Decl(self-types-non-zero-number.ts, 7, 5)) +>a : Symbol(a, Decl(self-types-non-zero-number.ts, 7, 16)) +>b : Symbol(b, Decl(self-types-non-zero-number.ts, 7, 26)) +>NonZeroNumber : Symbol(NonZeroNumber, Decl(self-types-non-zero-number.ts, 0, 0)) +>a : Symbol(a, Decl(self-types-non-zero-number.ts, 7, 16)) +>b : Symbol(b, Decl(self-types-non-zero-number.ts, 7, 26)) +>NonZeroNumber : Symbol(NonZeroNumber, Decl(self-types-non-zero-number.ts, 0, 0)) + +divide(1, 0) +>divide : Symbol(divide, Decl(self-types-non-zero-number.ts, 7, 5)) + +divide(1, 1) +>divide : Symbol(divide, Decl(self-types-non-zero-number.ts, 7, 5)) + +divide(1, "x") +>divide : Symbol(divide, Decl(self-types-non-zero-number.ts, 7, 5)) + +export {} diff --git a/tests/baselines/reference/self-types-non-zero-number.types b/tests/baselines/reference/self-types-non-zero-number.types new file mode 100644 index 0000000000000..b4300f3ea3067 --- /dev/null +++ b/tests/baselines/reference/self-types-non-zero-number.types @@ -0,0 +1,42 @@ +=== tests/cases/compiler/self-types-non-zero-number.ts === +type NonZeroNumber = +>NonZeroNumber : NonZeroNumber + + self extends number + ? self extends 0 + ? Never<`Type '${Print}' is not assignable to type 'NonZeroNumber'`> + : self + : number + +const divide = (a: number, b: NonZeroNumber) => (a / (b as number)) as NonZeroNumber +>divide : (a: number, b: NonZeroNumber) => NonZeroNumber +>(a: number, b: NonZeroNumber) => (a / (b as number)) as NonZeroNumber : (a: number, b: NonZeroNumber) => NonZeroNumber +>a : number +>b : NonZeroNumber +>(a / (b as number)) as NonZeroNumber : NonZeroNumber +>(a / (b as number)) : number +>a / (b as number) : number +>a : number +>(b as number) : number +>b as number : number +>b : NonZeroNumber + +divide(1, 0) +>divide(1, 0) : NonZeroNumber +>divide : (a: number, b: NonZeroNumber) => NonZeroNumber +>1 : 1 +>0 : 0 + +divide(1, 1) +>divide(1, 1) : NonZeroNumber +>divide : (a: number, b: NonZeroNumber) => NonZeroNumber +>1 : 1 +>1 : 1 + +divide(1, "x") +>divide(1, "x") : NonZeroNumber +>divide : (a: number, b: NonZeroNumber) => NonZeroNumber +>1 : 1 +>"x" : "x" + +export {} diff --git a/tests/baselines/reference/self-types-not.errors.txt b/tests/baselines/reference/self-types-not.errors.txt new file mode 100644 index 0000000000000..2678c591ca7a3 --- /dev/null +++ b/tests/baselines/reference/self-types-not.errors.txt @@ -0,0 +1,25 @@ +tests/cases/compiler/self-types-not.ts(8,11): error TS2345: Argument of type 'number' is not assignable to parameter of type 'number & Not<0>'. + Type '0' is not assignable to type 'Not<0>' +tests/cases/compiler/self-types-not.ts(10,11): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number & Not<0>'. + Type 'string' is not assignable to type 'number'. + + +==== tests/cases/compiler/self-types-not.ts (2 errors) ==== + type Not = + self extends T + ? Never<`Type '${Print}' is not assignable to type 'Not<${Print}>'`> + : self + + const divide = (a: number, b: number & Not<0>) => a / b + + divide(1, 0) + ~ +!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'number & Not<0>'. +!!! error TS2345: Type '0' is not assignable to type 'Not<0>' + divide(1, 1) + divide(1, "x") + ~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'number & Not<0>'. +!!! error TS2345: Type 'string' is not assignable to type 'number'. + + export {} \ No newline at end of file diff --git a/tests/baselines/reference/self-types-not.js b/tests/baselines/reference/self-types-not.js new file mode 100644 index 0000000000000..b5d6ef64d2176 --- /dev/null +++ b/tests/baselines/reference/self-types-not.js @@ -0,0 +1,21 @@ +//// [self-types-not.ts] +type Not = + self extends T + ? Never<`Type '${Print}' is not assignable to type 'Not<${Print}>'`> + : self + +const divide = (a: number, b: number & Not<0>) => a / b + +divide(1, 0) +divide(1, 1) +divide(1, "x") + +export {} + +//// [self-types-not.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var divide = function (a, b) { return a / b; }; +divide(1, 0); +divide(1, 1); +divide(1, "x"); diff --git a/tests/baselines/reference/self-types-not.symbols b/tests/baselines/reference/self-types-not.symbols new file mode 100644 index 0000000000000..17a4fa4f75254 --- /dev/null +++ b/tests/baselines/reference/self-types-not.symbols @@ -0,0 +1,34 @@ +=== tests/cases/compiler/self-types-not.ts === +type Not = +>Not : Symbol(Not, Decl(self-types-not.ts, 0, 0)) +>T : Symbol(T, Decl(self-types-not.ts, 0, 9)) + + self extends T +>T : Symbol(T, Decl(self-types-not.ts, 0, 9)) + + ? Never<`Type '${Print}' is not assignable to type 'Not<${Print}>'`> +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-not.ts, 0, 9)) + + : self + +const divide = (a: number, b: number & Not<0>) => a / b +>divide : Symbol(divide, Decl(self-types-not.ts, 5, 5)) +>a : Symbol(a, Decl(self-types-not.ts, 5, 16)) +>b : Symbol(b, Decl(self-types-not.ts, 5, 26)) +>Not : Symbol(Not, Decl(self-types-not.ts, 0, 0)) +>a : Symbol(a, Decl(self-types-not.ts, 5, 16)) +>b : Symbol(b, Decl(self-types-not.ts, 5, 26)) + +divide(1, 0) +>divide : Symbol(divide, Decl(self-types-not.ts, 5, 5)) + +divide(1, 1) +>divide : Symbol(divide, Decl(self-types-not.ts, 5, 5)) + +divide(1, "x") +>divide : Symbol(divide, Decl(self-types-not.ts, 5, 5)) + +export {} diff --git a/tests/baselines/reference/self-types-not.types b/tests/baselines/reference/self-types-not.types new file mode 100644 index 0000000000000..f11743de3e712 --- /dev/null +++ b/tests/baselines/reference/self-types-not.types @@ -0,0 +1,36 @@ +=== tests/cases/compiler/self-types-not.ts === +type Not = +>Not : Not + + self extends T + ? Never<`Type '${Print}' is not assignable to type 'Not<${Print}>'`> + : self + +const divide = (a: number, b: number & Not<0>) => a / b +>divide : (a: number, b: number & Not<0>) => number +>(a: number, b: number & Not<0>) => a / b : (a: number, b: number & Not<0>) => number +>a : number +>b : number & Not<0> +>a / b : number +>a : number +>b : number & Not<0> + +divide(1, 0) +>divide(1, 0) : number +>divide : (a: number, b: number & Not<0>) => number +>1 : 1 +>0 : 0 + +divide(1, 1) +>divide(1, 1) : number +>divide : (a: number, b: number & Not<0>) => number +>1 : 1 +>1 : 1 + +divide(1, "x") +>divide(1, "x") : number +>divide : (a: number, b: number & Not<0>) => number +>1 : 1 +>"x" : "x" + +export {} diff --git a/tests/baselines/reference/self-types-probability.errors.txt b/tests/baselines/reference/self-types-probability.errors.txt new file mode 100644 index 0000000000000..e34652eedbda8 --- /dev/null +++ b/tests/baselines/reference/self-types-probability.errors.txt @@ -0,0 +1,56 @@ +tests/cases/compiler/self-types-probability.ts(4,5): error TS18051: Type '1.5' is not assignable to type 'Probability' +tests/cases/compiler/self-types-probability.ts(5,5): error TS18051: Type '-0.5' is not assignable to type 'Probability' +tests/cases/compiler/self-types-probability.ts(6,5): error TS18051: Type 'number' is not assignable to type 'Probability' +tests/cases/compiler/self-types-probability.ts(8,5): error TS18051: Type 'number' is not assignable to type 'Probability' +tests/cases/compiler/self-types-probability.ts(18,18): error TS2344: Type 'Probability extends number ? true : false' does not satisfy the constraint 'true'. + Type 'boolean' is not assignable to type 'true'. + + +==== tests/cases/compiler/self-types-probability.ts (5 errors) ==== + let t0: Probability = 0.5 + let t1: Probability = 0 + let t2: Probability = 1 + let t3: Probability = 1.5 + ~~ +!!! error TS18051: Type '1.5' is not assignable to type 'Probability' + let t4: Probability = -0.5 + ~~ +!!! error TS18051: Type '-0.5' is not assignable to type 'Probability' + let t5: Probability = 0 as number + ~~ +!!! error TS18051: Type 'number' is not assignable to type 'Probability' + let t6: number = 0.5 as Probability + let t7: Probability = t0 + t1 + ~~ +!!! error TS18051: Type 'number' is not assignable to type 'Probability' + let t8: number = t0 + t1 + + declare const f: (x: number) => void + f(t0) + + type F = T + type T0 = F + + // TODO: this should compile + type T1 = Assert + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2344: Type 'Probability extends number ? true : false' does not satisfy the constraint 'true'. +!!! error TS2344: Type 'boolean' is not assignable to type 'true'. + + type Probability = + self extends number + ? IsProbability extends true + ? self + : Never<`Type '${Print}' is not assignable to type 'Probability'`> + : number + + type IsProbability = + `${T}` extends `${infer H}${infer R}` + ? H extends "0" ? true : + H extends "1" ? R extends "" ? true : false : + false + : false + + type Assert = T + + export {} \ No newline at end of file diff --git a/tests/baselines/reference/self-types-probability.js b/tests/baselines/reference/self-types-probability.js new file mode 100644 index 0000000000000..2ca26cd9bf6b0 --- /dev/null +++ b/tests/baselines/reference/self-types-probability.js @@ -0,0 +1,51 @@ +//// [self-types-probability.ts] +let t0: Probability = 0.5 +let t1: Probability = 0 +let t2: Probability = 1 +let t3: Probability = 1.5 +let t4: Probability = -0.5 +let t5: Probability = 0 as number +let t6: number = 0.5 as Probability +let t7: Probability = t0 + t1 +let t8: number = t0 + t1 + +declare const f: (x: number) => void +f(t0) + +type F = T +type T0 = F + +// TODO: this should compile +type T1 = Assert + +type Probability = + self extends number + ? IsProbability extends true + ? self + : Never<`Type '${Print}' is not assignable to type 'Probability'`> + : number + +type IsProbability = + `${T}` extends `${infer H}${infer R}` + ? H extends "0" ? true : + H extends "1" ? R extends "" ? true : false : + false + : false + +type Assert = T + +export {} + +//// [self-types-probability.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var t0 = 0.5; +var t1 = 0; +var t2 = 1; +var t3 = 1.5; +var t4 = -0.5; +var t5 = 0; +var t6 = 0.5; +var t7 = t0 + t1; +var t8 = t0 + t1; +f(t0); diff --git a/tests/baselines/reference/self-types-probability.symbols b/tests/baselines/reference/self-types-probability.symbols new file mode 100644 index 0000000000000..c596ab6ca9cb7 --- /dev/null +++ b/tests/baselines/reference/self-types-probability.symbols @@ -0,0 +1,103 @@ +=== tests/cases/compiler/self-types-probability.ts === +let t0: Probability = 0.5 +>t0 : Symbol(t0, Decl(self-types-probability.ts, 0, 3)) +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) + +let t1: Probability = 0 +>t1 : Symbol(t1, Decl(self-types-probability.ts, 1, 3)) +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) + +let t2: Probability = 1 +>t2 : Symbol(t2, Decl(self-types-probability.ts, 2, 3)) +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) + +let t3: Probability = 1.5 +>t3 : Symbol(t3, Decl(self-types-probability.ts, 3, 3)) +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) + +let t4: Probability = -0.5 +>t4 : Symbol(t4, Decl(self-types-probability.ts, 4, 3)) +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) + +let t5: Probability = 0 as number +>t5 : Symbol(t5, Decl(self-types-probability.ts, 5, 3)) +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) + +let t6: number = 0.5 as Probability +>t6 : Symbol(t6, Decl(self-types-probability.ts, 6, 3)) +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) + +let t7: Probability = t0 + t1 +>t7 : Symbol(t7, Decl(self-types-probability.ts, 7, 3)) +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) +>t0 : Symbol(t0, Decl(self-types-probability.ts, 0, 3)) +>t1 : Symbol(t1, Decl(self-types-probability.ts, 1, 3)) + +let t8: number = t0 + t1 +>t8 : Symbol(t8, Decl(self-types-probability.ts, 8, 3)) +>t0 : Symbol(t0, Decl(self-types-probability.ts, 0, 3)) +>t1 : Symbol(t1, Decl(self-types-probability.ts, 1, 3)) + +declare const f: (x: number) => void +>f : Symbol(f, Decl(self-types-probability.ts, 10, 13)) +>x : Symbol(x, Decl(self-types-probability.ts, 10, 18)) + +f(t0) +>f : Symbol(f, Decl(self-types-probability.ts, 10, 13)) +>t0 : Symbol(t0, Decl(self-types-probability.ts, 0, 3)) + +type F = T +>F : Symbol(F, Decl(self-types-probability.ts, 11, 5)) +>T : Symbol(T, Decl(self-types-probability.ts, 13, 7)) +>T : Symbol(T, Decl(self-types-probability.ts, 13, 7)) + +type T0 = F +>T0 : Symbol(T0, Decl(self-types-probability.ts, 13, 28)) +>F : Symbol(F, Decl(self-types-probability.ts, 11, 5)) +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) + +// TODO: this should compile +type T1 = Assert +>T1 : Symbol(T1, Decl(self-types-probability.ts, 14, 24)) +>Assert : Symbol(Assert, Decl(self-types-probability.ts, 31, 13)) +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) + +type Probability = +>Probability : Symbol(Probability, Decl(self-types-probability.ts, 17, 59)) + + self extends number + ? IsProbability extends true +>IsProbability : Symbol(IsProbability, Decl(self-types-probability.ts, 24, 12)) + + ? self + : Never<`Type '${Print}' is not assignable to type 'Probability'`> +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) + + : number + +type IsProbability = +>IsProbability : Symbol(IsProbability, Decl(self-types-probability.ts, 24, 12)) +>T : Symbol(T, Decl(self-types-probability.ts, 26, 19)) + + `${T}` extends `${infer H}${infer R}` +>T : Symbol(T, Decl(self-types-probability.ts, 26, 19)) +>H : Symbol(H, Decl(self-types-probability.ts, 27, 25)) +>R : Symbol(R, Decl(self-types-probability.ts, 27, 35)) + + ? H extends "0" ? true : +>H : Symbol(H, Decl(self-types-probability.ts, 27, 25)) + + H extends "1" ? R extends "" ? true : false : +>H : Symbol(H, Decl(self-types-probability.ts, 27, 25)) +>R : Symbol(R, Decl(self-types-probability.ts, 27, 35)) + + false + : false + +type Assert = T +>Assert : Symbol(Assert, Decl(self-types-probability.ts, 31, 13)) +>T : Symbol(T, Decl(self-types-probability.ts, 33, 12)) +>T : Symbol(T, Decl(self-types-probability.ts, 33, 12)) + +export {} diff --git a/tests/baselines/reference/self-types-probability.types b/tests/baselines/reference/self-types-probability.types new file mode 100644 index 0000000000000..2b3b541391d8f --- /dev/null +++ b/tests/baselines/reference/self-types-probability.types @@ -0,0 +1,98 @@ +=== tests/cases/compiler/self-types-probability.ts === +let t0: Probability = 0.5 +>t0 : Probability +>0.5 : 0.5 + +let t1: Probability = 0 +>t1 : Probability +>0 : 0 + +let t2: Probability = 1 +>t2 : Probability +>1 : 1 + +let t3: Probability = 1.5 +>t3 : Probability +>1.5 : 1.5 + +let t4: Probability = -0.5 +>t4 : Probability +>-0.5 : -0.5 +>0.5 : 0.5 + +let t5: Probability = 0 as number +>t5 : Probability +>0 as number : number +>0 : 0 + +let t6: number = 0.5 as Probability +>t6 : number +>0.5 as Probability : Probability +>0.5 : 0.5 + +let t7: Probability = t0 + t1 +>t7 : Probability +>t0 + t1 : number +>t0 : Probability +>t1 : Probability + +let t8: number = t0 + t1 +>t8 : number +>t0 + t1 : number +>t0 : Probability +>t1 : Probability + +declare const f: (x: number) => void +>f : (x: number) => void +>x : number + +f(t0) +>f(t0) : void +>f : (x: number) => void +>t0 : Probability + +type F = T +>F : T + +type T0 = F +>T0 : Probability + +// TODO: this should compile +type T1 = Assert +>T1 : Probability extends number ? true : false +>true : true +>false : false + +type Probability = +>Probability : Probability + + self extends number + ? IsProbability extends true +>true : true + + ? self + : Never<`Type '${Print}' is not assignable to type 'Probability'`> + : number + +type IsProbability = +>IsProbability : IsProbability + + `${T}` extends `${infer H}${infer R}` + ? H extends "0" ? true : +>true : true + + H extends "1" ? R extends "" ? true : false : +>true : true +>false : false + + false +>false : false + + : false +>false : false + +type Assert = T +>Assert : T +>true : true + +export {} diff --git a/tests/baselines/reference/self-types-ryan.errors.txt b/tests/baselines/reference/self-types-ryan.errors.txt new file mode 100644 index 0000000000000..14d183b4933c9 --- /dev/null +++ b/tests/baselines/reference/self-types-ryan.errors.txt @@ -0,0 +1,90 @@ +tests/cases/compiler/self-types-ryan.ts(24,11): error TS18051: Type '"Acept"' is not assignable to type 'CaseInsensitive<"Set-Cookie" | "Accept">' + Type 'Lowercase<"Acept">' is not assignable to 'Lowercase<"Set-Cookie" | "Accept">' + Type '"acept"' is not assignable to '"set-cookie" | "accept"' +tests/cases/compiler/self-types-ryan.ts(38,10): error TS18051: Type '"XYZ"' is not assignable to type 'CaseInsensitive<"bar">' + Type 'Lowercase<"XYZ">' is not assignable to 'Lowercase<"bar">' + Type '"xyz"' is not assignable to '"bar"' +tests/cases/compiler/self-types-ryan.ts(42,7): error TS2322: Type 'CaseInsensitive' is not assignable to type 'AnyString1'. + Type 'T | (Lowercase extends Lowercase ? self : never)' is not assignable to type 'AnyString1'. + Type 'T' is not assignable to type 'AnyString1'. + Type 'string' is not assignable to type 'AnyString1'. +tests/cases/compiler/self-types-ryan.ts(43,7): error TS2322: Type 'string' is not assignable to type 'T'. + 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string'. +tests/cases/compiler/self-types-ryan.ts(48,7): error TS2322: Type 'CaseInsensitive' is not assignable to type 'AnyString2'. + Type 'T | (Lowercase extends Lowercase ? self : never)' is not assignable to type 'AnyString2'. + Type 'T' is not assignable to type 'AnyString2'. + Type 'string' is not assignable to type 'AnyString2'. + + +==== tests/cases/compiler/self-types-ryan.ts (5 errors) ==== + type CaseInsensitive = + self extends string + ? Lowercase extends Lowercase + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'CaseInsensitive<${Print}>'`, + `Type 'Lowercase<${Print}>' is not assignable to 'Lowercase<${Print}>'`, + `Type '${Print>}' is not assignable to '${Print>}'` + ]> + : T + + type Box = { value: T }; + type Fooish = CaseInsensitive<"Foo">; + const x1: CaseInsensitive<"Foo"> = "FOO"; + const x2: Fooish = "FOO"; + const x3: Box> = { value: "FOO" }; + const x4: Box = { value: "FOO" }; + + type HeaderNames = CaseInsensitive<"Set-Cookie" | "Accept">; + declare const setHeader: (key: HeaderNames, value: string) => void + setHeader("Set-Cookie", "test") + setHeader("Accept", "test2") + setHeader("sEt-cOoKiE", "stop writing headers like this but ok") + setHeader("Acept", "nah this has a typo") + ~~~~~~~ +!!! error TS18051: Type '"Acept"' is not assignable to type 'CaseInsensitive<"Set-Cookie" | "Accept">' +!!! error TS18051: Type 'Lowercase<"Acept">' is not assignable to 'Lowercase<"Set-Cookie" | "Accept">' +!!! error TS18051: Type '"acept"' is not assignable to '"set-cookie" | "accept"' + + type DistributeCaseInsensitive = T extends unknown ? CaseInsensitive : never; + let m: DistributeCaseInsensitive<"A" | "B"> = "a" + + type BarIfFoo = + T extends "foo" + ? CaseInsensitive<"bar"> + : never + + declare const f: + (x: T, y: BarIfFoo) => void + + f("foo", "BAR") + f("foo", "XYZ") + ~~~~~ +!!! error TS18051: Type '"XYZ"' is not assignable to type 'CaseInsensitive<"bar">' +!!! error TS18051: Type 'Lowercase<"XYZ">' is not assignable to 'Lowercase<"bar">' +!!! error TS18051: Type '"xyz"' is not assignable to '"bar"' + + type AnyString1 = self extends string ? T : never; + function foo1(a: CaseInsensitive) { + let m: AnyString1 = a; + ~ +!!! error TS2322: Type 'CaseInsensitive' is not assignable to type 'AnyString1'. +!!! error TS2322: Type 'T | (Lowercase extends Lowercase ? self : never)' is not assignable to type 'AnyString1'. +!!! error TS2322: Type 'T' is not assignable to type 'AnyString1'. +!!! error TS2322: Type 'string' is not assignable to type 'AnyString1'. + let n: AnyString1 = {} as string; + ~ +!!! error TS2322: Type 'string' is not assignable to type 'T'. +!!! error TS2322: 'string' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'string'. + } + + type AnyString2 = self extends string ? self : never; + function foo2(a: CaseInsensitive) { + let m: AnyString2 = a; // TODO?: this should probably compile + ~ +!!! error TS2322: Type 'CaseInsensitive' is not assignable to type 'AnyString2'. +!!! error TS2322: Type 'T | (Lowercase extends Lowercase ? self : never)' is not assignable to type 'AnyString2'. +!!! error TS2322: Type 'T' is not assignable to type 'AnyString2'. +!!! error TS2322: Type 'string' is not assignable to type 'AnyString2'. + let n: AnyString2 = {} as string; + } \ No newline at end of file diff --git a/tests/baselines/reference/self-types-ryan.js b/tests/baselines/reference/self-types-ryan.js new file mode 100644 index 0000000000000..0b3d446b56089 --- /dev/null +++ b/tests/baselines/reference/self-types-ryan.js @@ -0,0 +1,72 @@ +//// [self-types-ryan.ts] +type CaseInsensitive = + self extends string + ? Lowercase extends Lowercase + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'CaseInsensitive<${Print}>'`, + `Type 'Lowercase<${Print}>' is not assignable to 'Lowercase<${Print}>'`, + `Type '${Print>}' is not assignable to '${Print>}'` + ]> + : T + +type Box = { value: T }; +type Fooish = CaseInsensitive<"Foo">; +const x1: CaseInsensitive<"Foo"> = "FOO"; +const x2: Fooish = "FOO"; +const x3: Box> = { value: "FOO" }; +const x4: Box = { value: "FOO" }; + +type HeaderNames = CaseInsensitive<"Set-Cookie" | "Accept">; +declare const setHeader: (key: HeaderNames, value: string) => void +setHeader("Set-Cookie", "test") +setHeader("Accept", "test2") +setHeader("sEt-cOoKiE", "stop writing headers like this but ok") +setHeader("Acept", "nah this has a typo") + +type DistributeCaseInsensitive = T extends unknown ? CaseInsensitive : never; +let m: DistributeCaseInsensitive<"A" | "B"> = "a" + +type BarIfFoo = + T extends "foo" + ? CaseInsensitive<"bar"> + : never + +declare const f: + (x: T, y: BarIfFoo) => void + +f("foo", "BAR") +f("foo", "XYZ") + +type AnyString1 = self extends string ? T : never; +function foo1(a: CaseInsensitive) { + let m: AnyString1 = a; + let n: AnyString1 = {} as string; +} + +type AnyString2 = self extends string ? self : never; +function foo2(a: CaseInsensitive) { + let m: AnyString2 = a; // TODO?: this should probably compile + let n: AnyString2 = {} as string; +} + +//// [self-types-ryan.js] +var x1 = "FOO"; +var x2 = "FOO"; +var x3 = { value: "FOO" }; +var x4 = { value: "FOO" }; +setHeader("Set-Cookie", "test"); +setHeader("Accept", "test2"); +setHeader("sEt-cOoKiE", "stop writing headers like this but ok"); +setHeader("Acept", "nah this has a typo"); +var m = "a"; +f("foo", "BAR"); +f("foo", "XYZ"); +function foo1(a) { + var m = a; + var n = {}; +} +function foo2(a) { + var m = a; // TODO?: this should probably compile + var n = {}; +} diff --git a/tests/baselines/reference/self-types-ryan.symbols b/tests/baselines/reference/self-types-ryan.symbols new file mode 100644 index 0000000000000..70005a023642f --- /dev/null +++ b/tests/baselines/reference/self-types-ryan.symbols @@ -0,0 +1,171 @@ +=== tests/cases/compiler/self-types-ryan.ts === +type CaseInsensitive = +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-ryan.ts, 0, 0)) +>T : Symbol(T, Decl(self-types-ryan.ts, 0, 21)) + + self extends string + ? Lowercase extends Lowercase +>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --)) +>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-ryan.ts, 0, 21)) + + ? self + : Never<[ +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) + + `Type '${Print}' is not assignable to type 'CaseInsensitive<${Print}>'`, +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-ryan.ts, 0, 21)) + + `Type 'Lowercase<${Print}>' is not assignable to 'Lowercase<${Print}>'`, +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-ryan.ts, 0, 21)) + + `Type '${Print>}' is not assignable to '${Print>}'` +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Lowercase : Symbol(Lowercase, Decl(lib.es5.d.ts, --, --)) +>T : Symbol(T, Decl(self-types-ryan.ts, 0, 21)) + + ]> + : T +>T : Symbol(T, Decl(self-types-ryan.ts, 0, 21)) + +type Box = { value: T }; +>Box : Symbol(Box, Decl(self-types-ryan.ts, 9, 7)) +>T : Symbol(T, Decl(self-types-ryan.ts, 11, 9)) +>value : Symbol(value, Decl(self-types-ryan.ts, 11, 15)) +>T : Symbol(T, Decl(self-types-ryan.ts, 11, 9)) + +type Fooish = CaseInsensitive<"Foo">; +>Fooish : Symbol(Fooish, Decl(self-types-ryan.ts, 11, 27)) +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-ryan.ts, 0, 0)) + +const x1: CaseInsensitive<"Foo"> = "FOO"; +>x1 : Symbol(x1, Decl(self-types-ryan.ts, 13, 5)) +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-ryan.ts, 0, 0)) + +const x2: Fooish = "FOO"; +>x2 : Symbol(x2, Decl(self-types-ryan.ts, 14, 5)) +>Fooish : Symbol(Fooish, Decl(self-types-ryan.ts, 11, 27)) + +const x3: Box> = { value: "FOO" }; +>x3 : Symbol(x3, Decl(self-types-ryan.ts, 15, 5)) +>Box : Symbol(Box, Decl(self-types-ryan.ts, 9, 7)) +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-ryan.ts, 0, 0)) +>value : Symbol(value, Decl(self-types-ryan.ts, 15, 41)) + +const x4: Box = { value: "FOO" }; +>x4 : Symbol(x4, Decl(self-types-ryan.ts, 16, 5)) +>Box : Symbol(Box, Decl(self-types-ryan.ts, 9, 7)) +>Fooish : Symbol(Fooish, Decl(self-types-ryan.ts, 11, 27)) +>value : Symbol(value, Decl(self-types-ryan.ts, 16, 25)) + +type HeaderNames = CaseInsensitive<"Set-Cookie" | "Accept">; +>HeaderNames : Symbol(HeaderNames, Decl(self-types-ryan.ts, 16, 41)) +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-ryan.ts, 0, 0)) + +declare const setHeader: (key: HeaderNames, value: string) => void +>setHeader : Symbol(setHeader, Decl(self-types-ryan.ts, 19, 13)) +>key : Symbol(key, Decl(self-types-ryan.ts, 19, 26)) +>HeaderNames : Symbol(HeaderNames, Decl(self-types-ryan.ts, 16, 41)) +>value : Symbol(value, Decl(self-types-ryan.ts, 19, 43)) + +setHeader("Set-Cookie", "test") +>setHeader : Symbol(setHeader, Decl(self-types-ryan.ts, 19, 13)) + +setHeader("Accept", "test2") +>setHeader : Symbol(setHeader, Decl(self-types-ryan.ts, 19, 13)) + +setHeader("sEt-cOoKiE", "stop writing headers like this but ok") +>setHeader : Symbol(setHeader, Decl(self-types-ryan.ts, 19, 13)) + +setHeader("Acept", "nah this has a typo") +>setHeader : Symbol(setHeader, Decl(self-types-ryan.ts, 19, 13)) + +type DistributeCaseInsensitive = T extends unknown ? CaseInsensitive : never; +>DistributeCaseInsensitive : Symbol(DistributeCaseInsensitive, Decl(self-types-ryan.ts, 23, 41)) +>T : Symbol(T, Decl(self-types-ryan.ts, 25, 31)) +>T : Symbol(T, Decl(self-types-ryan.ts, 25, 31)) +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-ryan.ts, 0, 0)) +>T : Symbol(T, Decl(self-types-ryan.ts, 25, 31)) + +let m: DistributeCaseInsensitive<"A" | "B"> = "a" +>m : Symbol(m, Decl(self-types-ryan.ts, 26, 3)) +>DistributeCaseInsensitive : Symbol(DistributeCaseInsensitive, Decl(self-types-ryan.ts, 23, 41)) + +type BarIfFoo = +>BarIfFoo : Symbol(BarIfFoo, Decl(self-types-ryan.ts, 26, 49)) +>T : Symbol(T, Decl(self-types-ryan.ts, 28, 14)) + + T extends "foo" +>T : Symbol(T, Decl(self-types-ryan.ts, 28, 14)) + + ? CaseInsensitive<"bar"> +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-ryan.ts, 0, 0)) + + : never + +declare const f: +>f : Symbol(f, Decl(self-types-ryan.ts, 33, 13)) + + (x: T, y: BarIfFoo) => void +>T : Symbol(T, Decl(self-types-ryan.ts, 34, 3)) +>x : Symbol(x, Decl(self-types-ryan.ts, 34, 21)) +>T : Symbol(T, Decl(self-types-ryan.ts, 34, 3)) +>y : Symbol(y, Decl(self-types-ryan.ts, 34, 26)) +>BarIfFoo : Symbol(BarIfFoo, Decl(self-types-ryan.ts, 26, 49)) +>T : Symbol(T, Decl(self-types-ryan.ts, 34, 3)) + +f("foo", "BAR") +>f : Symbol(f, Decl(self-types-ryan.ts, 33, 13)) + +f("foo", "XYZ") +>f : Symbol(f, Decl(self-types-ryan.ts, 33, 13)) + +type AnyString1 = self extends string ? T : never; +>AnyString1 : Symbol(AnyString1, Decl(self-types-ryan.ts, 37, 15)) +>T : Symbol(T, Decl(self-types-ryan.ts, 39, 16)) +>T : Symbol(T, Decl(self-types-ryan.ts, 39, 16)) + +function foo1(a: CaseInsensitive) { +>foo1 : Symbol(foo1, Decl(self-types-ryan.ts, 39, 53)) +>T : Symbol(T, Decl(self-types-ryan.ts, 40, 14)) +>a : Symbol(a, Decl(self-types-ryan.ts, 40, 32)) +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-ryan.ts, 0, 0)) +>T : Symbol(T, Decl(self-types-ryan.ts, 40, 14)) + + let m: AnyString1 = a; +>m : Symbol(m, Decl(self-types-ryan.ts, 41, 5)) +>AnyString1 : Symbol(AnyString1, Decl(self-types-ryan.ts, 37, 15)) +>T : Symbol(T, Decl(self-types-ryan.ts, 40, 14)) +>a : Symbol(a, Decl(self-types-ryan.ts, 40, 32)) + + let n: AnyString1 = {} as string; +>n : Symbol(n, Decl(self-types-ryan.ts, 42, 5)) +>AnyString1 : Symbol(AnyString1, Decl(self-types-ryan.ts, 37, 15)) +>T : Symbol(T, Decl(self-types-ryan.ts, 40, 14)) +} + +type AnyString2 = self extends string ? self : never; +>AnyString2 : Symbol(AnyString2, Decl(self-types-ryan.ts, 43, 1)) + +function foo2(a: CaseInsensitive) { +>foo2 : Symbol(foo2, Decl(self-types-ryan.ts, 45, 53)) +>T : Symbol(T, Decl(self-types-ryan.ts, 46, 14)) +>a : Symbol(a, Decl(self-types-ryan.ts, 46, 32)) +>CaseInsensitive : Symbol(CaseInsensitive, Decl(self-types-ryan.ts, 0, 0)) +>T : Symbol(T, Decl(self-types-ryan.ts, 46, 14)) + + let m: AnyString2 = a; // TODO?: this should probably compile +>m : Symbol(m, Decl(self-types-ryan.ts, 47, 5)) +>AnyString2 : Symbol(AnyString2, Decl(self-types-ryan.ts, 43, 1)) +>a : Symbol(a, Decl(self-types-ryan.ts, 46, 32)) + + let n: AnyString2 = {} as string; +>n : Symbol(n, Decl(self-types-ryan.ts, 48, 5)) +>AnyString2 : Symbol(AnyString2, Decl(self-types-ryan.ts, 43, 1)) +} diff --git a/tests/baselines/reference/self-types-ryan.types b/tests/baselines/reference/self-types-ryan.types new file mode 100644 index 0000000000000..483fa655a0bb7 --- /dev/null +++ b/tests/baselines/reference/self-types-ryan.types @@ -0,0 +1,139 @@ +=== tests/cases/compiler/self-types-ryan.ts === +type CaseInsensitive = +>CaseInsensitive : CaseInsensitive + + self extends string + ? Lowercase extends Lowercase + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'CaseInsensitive<${Print}>'`, + `Type 'Lowercase<${Print}>' is not assignable to 'Lowercase<${Print}>'`, + `Type '${Print>}' is not assignable to '${Print>}'` + ]> + : T + +type Box = { value: T }; +>Box : Box +>value : T + +type Fooish = CaseInsensitive<"Foo">; +>Fooish : CaseInsensitive<"Foo"> + +const x1: CaseInsensitive<"Foo"> = "FOO"; +>x1 : CaseInsensitive<"Foo"> +>"FOO" : "FOO" + +const x2: Fooish = "FOO"; +>x2 : CaseInsensitive<"Foo"> +>"FOO" : "FOO" + +const x3: Box> = { value: "FOO" }; +>x3 : Box> +>{ value: "FOO" } : { value: "FOO"; } +>value : "FOO" +>"FOO" : "FOO" + +const x4: Box = { value: "FOO" }; +>x4 : Box> +>{ value: "FOO" } : { value: "FOO"; } +>value : "FOO" +>"FOO" : "FOO" + +type HeaderNames = CaseInsensitive<"Set-Cookie" | "Accept">; +>HeaderNames : CaseInsensitive<"Set-Cookie" | "Accept"> + +declare const setHeader: (key: HeaderNames, value: string) => void +>setHeader : (key: HeaderNames, value: string) => void +>key : CaseInsensitive<"Set-Cookie" | "Accept"> +>value : string + +setHeader("Set-Cookie", "test") +>setHeader("Set-Cookie", "test") : void +>setHeader : (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void +>"Set-Cookie" : "Set-Cookie" +>"test" : "test" + +setHeader("Accept", "test2") +>setHeader("Accept", "test2") : void +>setHeader : (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void +>"Accept" : "Accept" +>"test2" : "test2" + +setHeader("sEt-cOoKiE", "stop writing headers like this but ok") +>setHeader("sEt-cOoKiE", "stop writing headers like this but ok") : void +>setHeader : (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void +>"sEt-cOoKiE" : "sEt-cOoKiE" +>"stop writing headers like this but ok" : "stop writing headers like this but ok" + +setHeader("Acept", "nah this has a typo") +>setHeader("Acept", "nah this has a typo") : void +>setHeader : (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void +>"Acept" : "Acept" +>"nah this has a typo" : "nah this has a typo" + +type DistributeCaseInsensitive = T extends unknown ? CaseInsensitive : never; +>DistributeCaseInsensitive : DistributeCaseInsensitive + +let m: DistributeCaseInsensitive<"A" | "B"> = "a" +>m : CaseInsensitive<"A"> | CaseInsensitive<"B"> +>"a" : "a" + +type BarIfFoo = +>BarIfFoo : BarIfFoo + + T extends "foo" + ? CaseInsensitive<"bar"> + : never + +declare const f: +>f : (x: T, y: BarIfFoo) => void + + (x: T, y: BarIfFoo) => void +>x : T +>y : BarIfFoo + +f("foo", "BAR") +>f("foo", "BAR") : void +>f : (x: T, y: BarIfFoo) => void +>"foo" : "foo" +>"BAR" : "BAR" + +f("foo", "XYZ") +>f("foo", "XYZ") : void +>f : (x: T, y: BarIfFoo) => void +>"foo" : "foo" +>"XYZ" : "XYZ" + +type AnyString1 = self extends string ? T : never; +>AnyString1 : AnyString1 + +function foo1(a: CaseInsensitive) { +>foo1 : (a: CaseInsensitive) => void +>a : CaseInsensitive + + let m: AnyString1 = a; +>m : AnyString1 +>a : CaseInsensitive + + let n: AnyString1 = {} as string; +>n : AnyString1 +>{} as string : string +>{} : {} +} + +type AnyString2 = self extends string ? self : never; +>AnyString2 : AnyString2 + +function foo2(a: CaseInsensitive) { +>foo2 : (a: CaseInsensitive) => void +>a : CaseInsensitive + + let m: AnyString2 = a; // TODO?: this should probably compile +>m : AnyString2 +>a : CaseInsensitive + + let n: AnyString2 = {} as string; +>n : AnyString2 +>{} as string : string +>{} : {} +} diff --git a/tests/baselines/reference/self-types-state-machine.errors.txt b/tests/baselines/reference/self-types-state-machine.errors.txt new file mode 100644 index 0000000000000..ce1a2f56f1d0b --- /dev/null +++ b/tests/baselines/reference/self-types-state-machine.errors.txt @@ -0,0 +1,30 @@ +tests/cases/compiler/self-types-state-machine.ts(4,5): error TS2322: Type '{ off: { ON: "red"; }; red: { TICK: "yellow"; OFF: "off"; }; yellow: { TICK: "green"; OFF: "off"; }; green: { TICK: "reddd"; OFF: "off"; }; }' is not assignable to type 'StateMachine'. + The types of 'green.TICK' are incompatible between these types. + Type '"reddd"' is not assignable to type '"off" | "red" | "yellow" | "green"'. Did you mean '"red"'? + + +==== tests/cases/compiler/self-types-state-machine.ts (1 errors) ==== + type StateMachine = + { [S in keyof self]: { [E in keyof self[S]]: keyof self } } + + let trafficLights: StateMachine = { + ~~~~~~~~~~~~~ +!!! error TS2322: Type '{ off: { ON: "red"; }; red: { TICK: "yellow"; OFF: "off"; }; yellow: { TICK: "green"; OFF: "off"; }; green: { TICK: "reddd"; OFF: "off"; }; }' is not assignable to type 'StateMachine'. +!!! error TS2322: The types of 'green.TICK' are incompatible between these types. +!!! error TS2322: Type '"reddd"' is not assignable to type '"off" | "red" | "yellow" | "green"'. Did you mean '"red"'? + off: { + ON: "red" + }, + red: { + TICK: "yellow", + OFF: "off" + }, + yellow: { + TICK: "green", + OFF: "off" + }, + green: { + TICK: "reddd", + OFF: "off" + } + } \ No newline at end of file diff --git a/tests/baselines/reference/self-types-state-machine.js b/tests/baselines/reference/self-types-state-machine.js new file mode 100644 index 0000000000000..1ffb4ff3985b5 --- /dev/null +++ b/tests/baselines/reference/self-types-state-machine.js @@ -0,0 +1,40 @@ +//// [self-types-state-machine.ts] +type StateMachine = + { [S in keyof self]: { [E in keyof self[S]]: keyof self } } + +let trafficLights: StateMachine = { + off: { + ON: "red" + }, + red: { + TICK: "yellow", + OFF: "off" + }, + yellow: { + TICK: "green", + OFF: "off" + }, + green: { + TICK: "reddd", + OFF: "off" + } +} + +//// [self-types-state-machine.js] +var trafficLights = { + off: { + ON: "red" + }, + red: { + TICK: "yellow", + OFF: "off" + }, + yellow: { + TICK: "green", + OFF: "off" + }, + green: { + TICK: "reddd", + OFF: "off" + } +}; diff --git a/tests/baselines/reference/self-types-state-machine.symbols b/tests/baselines/reference/self-types-state-machine.symbols new file mode 100644 index 0000000000000..f1031d7edf2f6 --- /dev/null +++ b/tests/baselines/reference/self-types-state-machine.symbols @@ -0,0 +1,50 @@ +=== tests/cases/compiler/self-types-state-machine.ts === +type StateMachine = +>StateMachine : Symbol(StateMachine, Decl(self-types-state-machine.ts, 0, 0)) + + { [S in keyof self]: { [E in keyof self[S]]: keyof self } } +>S : Symbol(S, Decl(self-types-state-machine.ts, 1, 5)) +>E : Symbol(E, Decl(self-types-state-machine.ts, 1, 26)) +>S : Symbol(S, Decl(self-types-state-machine.ts, 1, 5)) + +let trafficLights: StateMachine = { +>trafficLights : Symbol(trafficLights, Decl(self-types-state-machine.ts, 3, 3)) +>StateMachine : Symbol(StateMachine, Decl(self-types-state-machine.ts, 0, 0)) + + off: { +>off : Symbol(off, Decl(self-types-state-machine.ts, 3, 35)) + + ON: "red" +>ON : Symbol(ON, Decl(self-types-state-machine.ts, 4, 8)) + + }, + red: { +>red : Symbol(red, Decl(self-types-state-machine.ts, 6, 4)) + + TICK: "yellow", +>TICK : Symbol(TICK, Decl(self-types-state-machine.ts, 7, 8)) + + OFF: "off" +>OFF : Symbol(OFF, Decl(self-types-state-machine.ts, 8, 19)) + + }, + yellow: { +>yellow : Symbol(yellow, Decl(self-types-state-machine.ts, 10, 4)) + + TICK: "green", +>TICK : Symbol(TICK, Decl(self-types-state-machine.ts, 11, 11)) + + OFF: "off" +>OFF : Symbol(OFF, Decl(self-types-state-machine.ts, 12, 18)) + + }, + green: { +>green : Symbol(green, Decl(self-types-state-machine.ts, 14, 4)) + + TICK: "reddd", +>TICK : Symbol(TICK, Decl(self-types-state-machine.ts, 15, 10)) + + OFF: "off" +>OFF : Symbol(OFF, Decl(self-types-state-machine.ts, 16, 18)) + } +} diff --git a/tests/baselines/reference/self-types-state-machine.types b/tests/baselines/reference/self-types-state-machine.types new file mode 100644 index 0000000000000..902e0c1326562 --- /dev/null +++ b/tests/baselines/reference/self-types-state-machine.types @@ -0,0 +1,58 @@ +=== tests/cases/compiler/self-types-state-machine.ts === +type StateMachine = +>StateMachine : StateMachine + + { [S in keyof self]: { [E in keyof self[S]]: keyof self } } + +let trafficLights: StateMachine = { +>trafficLights : StateMachine +>{ off: { ON: "red" }, red: { TICK: "yellow", OFF: "off" }, yellow: { TICK: "green", OFF: "off" }, green: { TICK: "reddd", OFF: "off" }} : { off: { ON: "red"; }; red: { TICK: "yellow"; OFF: "off"; }; yellow: { TICK: "green"; OFF: "off"; }; green: { TICK: "reddd"; OFF: "off"; }; } + + off: { +>off : { ON: "red"; } +>{ ON: "red" } : { ON: "red"; } + + ON: "red" +>ON : "red" +>"red" : "red" + + }, + red: { +>red : { TICK: "yellow"; OFF: "off"; } +>{ TICK: "yellow", OFF: "off" } : { TICK: "yellow"; OFF: "off"; } + + TICK: "yellow", +>TICK : "yellow" +>"yellow" : "yellow" + + OFF: "off" +>OFF : "off" +>"off" : "off" + + }, + yellow: { +>yellow : { TICK: "green"; OFF: "off"; } +>{ TICK: "green", OFF: "off" } : { TICK: "green"; OFF: "off"; } + + TICK: "green", +>TICK : "green" +>"green" : "green" + + OFF: "off" +>OFF : "off" +>"off" : "off" + + }, + green: { +>green : { TICK: "reddd"; OFF: "off"; } +>{ TICK: "reddd", OFF: "off" } : { TICK: "reddd"; OFF: "off"; } + + TICK: "reddd", +>TICK : "reddd" +>"reddd" : "reddd" + + OFF: "off" +>OFF : "off" +>"off" : "off" + } +} diff --git a/tests/baselines/reference/self-types-string-literal.errors.txt b/tests/baselines/reference/self-types-string-literal.errors.txt new file mode 100644 index 0000000000000..ba03c79235e58 --- /dev/null +++ b/tests/baselines/reference/self-types-string-literal.errors.txt @@ -0,0 +1,29 @@ +tests/cases/compiler/self-types-string-literal.ts(9,5): error TS18051: Type 'string' is not assignable to type 'StringLiteral' +tests/cases/compiler/self-types-string-literal.ts(11,34): error TS18051: Type 'string' is not assignable to type 'StringLiteral' +tests/cases/compiler/self-types-string-literal.ts(12,42): error TS18051: Type 'string' is not assignable to type 'StringLiteral' + + +==== tests/cases/compiler/self-types-string-literal.ts (3 errors) ==== + type StringLiteral = + self extends string + ? string extends self + ? Never<`Type '${Print}' is not assignable to type 'StringLiteral'`> + : self + : string + + let x: StringLiteral = "x" as "x" + let y: StringLiteral = "y" as string + ~ +!!! error TS18051: Type 'string' is not assignable to type 'StringLiteral' + let xx: { x: StringLiteral } = { x: "x" as "x" } + let yy: { y: StringLiteral } = { y: "y" as string } + ~ +!!! error TS18051: Type 'string' is not assignable to type 'StringLiteral' +!!! related TS6500 tests/cases/compiler/self-types-string-literal.ts:11:11: The expected type comes from property 'y' which is declared here on type '{ y: StringLiteral; }' + let zs: StringLiteral[] = ["z0" as "z0", "z1" as string, "z2" as "z2"] + ~~~~~~~~~~~~~~ +!!! error TS18051: Type 'string' is not assignable to type 'StringLiteral' + let a: StringLiteral = "a" as StringLiteral + let b: StringLiteral = "b" + let cs: StringLiteral[] = ["c0", "c1", "c2"] + \ No newline at end of file diff --git a/tests/baselines/reference/self-types-string-literal.js b/tests/baselines/reference/self-types-string-literal.js new file mode 100644 index 0000000000000..316eb7aea0b6a --- /dev/null +++ b/tests/baselines/reference/self-types-string-literal.js @@ -0,0 +1,27 @@ +//// [self-types-string-literal.ts] +type StringLiteral = + self extends string + ? string extends self + ? Never<`Type '${Print}' is not assignable to type 'StringLiteral'`> + : self + : string + +let x: StringLiteral = "x" as "x" +let y: StringLiteral = "y" as string +let xx: { x: StringLiteral } = { x: "x" as "x" } +let yy: { y: StringLiteral } = { y: "y" as string } +let zs: StringLiteral[] = ["z0" as "z0", "z1" as string, "z2" as "z2"] +let a: StringLiteral = "a" as StringLiteral +let b: StringLiteral = "b" +let cs: StringLiteral[] = ["c0", "c1", "c2"] + + +//// [self-types-string-literal.js] +var x = "x"; +var y = "y"; +var xx = { x: "x" }; +var yy = { y: "y" }; +var zs = ["z0", "z1", "z2"]; +var a = "a"; +var b = "b"; +var cs = ["c0", "c1", "c2"]; diff --git a/tests/baselines/reference/self-types-string-literal.symbols b/tests/baselines/reference/self-types-string-literal.symbols new file mode 100644 index 0000000000000..7e256655b96d0 --- /dev/null +++ b/tests/baselines/reference/self-types-string-literal.symbols @@ -0,0 +1,50 @@ +=== tests/cases/compiler/self-types-string-literal.ts === +type StringLiteral = +>StringLiteral : Symbol(StringLiteral, Decl(self-types-string-literal.ts, 0, 0)) + + self extends string + ? string extends self + ? Never<`Type '${Print}' is not assignable to type 'StringLiteral'`> +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) + + : self + : string + +let x: StringLiteral = "x" as "x" +>x : Symbol(x, Decl(self-types-string-literal.ts, 7, 3)) +>StringLiteral : Symbol(StringLiteral, Decl(self-types-string-literal.ts, 0, 0)) + +let y: StringLiteral = "y" as string +>y : Symbol(y, Decl(self-types-string-literal.ts, 8, 3)) +>StringLiteral : Symbol(StringLiteral, Decl(self-types-string-literal.ts, 0, 0)) + +let xx: { x: StringLiteral } = { x: "x" as "x" } +>xx : Symbol(xx, Decl(self-types-string-literal.ts, 9, 3)) +>x : Symbol(x, Decl(self-types-string-literal.ts, 9, 9)) +>StringLiteral : Symbol(StringLiteral, Decl(self-types-string-literal.ts, 0, 0)) +>x : Symbol(x, Decl(self-types-string-literal.ts, 9, 32)) + +let yy: { y: StringLiteral } = { y: "y" as string } +>yy : Symbol(yy, Decl(self-types-string-literal.ts, 10, 3)) +>y : Symbol(y, Decl(self-types-string-literal.ts, 10, 9)) +>StringLiteral : Symbol(StringLiteral, Decl(self-types-string-literal.ts, 0, 0)) +>y : Symbol(y, Decl(self-types-string-literal.ts, 10, 32)) + +let zs: StringLiteral[] = ["z0" as "z0", "z1" as string, "z2" as "z2"] +>zs : Symbol(zs, Decl(self-types-string-literal.ts, 11, 3)) +>StringLiteral : Symbol(StringLiteral, Decl(self-types-string-literal.ts, 0, 0)) + +let a: StringLiteral = "a" as StringLiteral +>a : Symbol(a, Decl(self-types-string-literal.ts, 12, 3)) +>StringLiteral : Symbol(StringLiteral, Decl(self-types-string-literal.ts, 0, 0)) +>StringLiteral : Symbol(StringLiteral, Decl(self-types-string-literal.ts, 0, 0)) + +let b: StringLiteral = "b" +>b : Symbol(b, Decl(self-types-string-literal.ts, 13, 3)) +>StringLiteral : Symbol(StringLiteral, Decl(self-types-string-literal.ts, 0, 0)) + +let cs: StringLiteral[] = ["c0", "c1", "c2"] +>cs : Symbol(cs, Decl(self-types-string-literal.ts, 14, 3)) +>StringLiteral : Symbol(StringLiteral, Decl(self-types-string-literal.ts, 0, 0)) + diff --git a/tests/baselines/reference/self-types-string-literal.types b/tests/baselines/reference/self-types-string-literal.types new file mode 100644 index 0000000000000..932a6627565cb --- /dev/null +++ b/tests/baselines/reference/self-types-string-literal.types @@ -0,0 +1,62 @@ +=== tests/cases/compiler/self-types-string-literal.ts === +type StringLiteral = +>StringLiteral : StringLiteral + + self extends string + ? string extends self + ? Never<`Type '${Print}' is not assignable to type 'StringLiteral'`> + : self + : string + +let x: StringLiteral = "x" as "x" +>x : StringLiteral +>"x" as "x" : "x" +>"x" : "x" + +let y: StringLiteral = "y" as string +>y : StringLiteral +>"y" as string : string +>"y" : "y" + +let xx: { x: StringLiteral } = { x: "x" as "x" } +>xx : { x: StringLiteral; } +>x : StringLiteral +>{ x: "x" as "x" } : { x: "x"; } +>x : "x" +>"x" as "x" : "x" +>"x" : "x" + +let yy: { y: StringLiteral } = { y: "y" as string } +>yy : { y: StringLiteral; } +>y : StringLiteral +>{ y: "y" as string } : { y: string; } +>y : string +>"y" as string : string +>"y" : "y" + +let zs: StringLiteral[] = ["z0" as "z0", "z1" as string, "z2" as "z2"] +>zs : StringLiteral[] +>["z0" as "z0", "z1" as string, "z2" as "z2"] : string[] +>"z0" as "z0" : "z0" +>"z0" : "z0" +>"z1" as string : string +>"z1" : "z1" +>"z2" as "z2" : "z2" +>"z2" : "z2" + +let a: StringLiteral = "a" as StringLiteral +>a : StringLiteral +>"a" as StringLiteral : StringLiteral +>"a" : "a" + +let b: StringLiteral = "b" +>b : StringLiteral +>"b" : "b" + +let cs: StringLiteral[] = ["c0", "c1", "c2"] +>cs : StringLiteral[] +>["c0", "c1", "c2"] : ("c0" | "c1" | "c2")[] +>"c0" : "c0" +>"c1" : "c1" +>"c2" : "c2" + diff --git a/tests/baselines/reference/self-types-tuple-from-union.errors.txt b/tests/baselines/reference/self-types-tuple-from-union.errors.txt new file mode 100644 index 0000000000000..bace668795218 --- /dev/null +++ b/tests/baselines/reference/self-types-tuple-from-union.errors.txt @@ -0,0 +1,72 @@ +tests/cases/compiler/self-types-tuple-from-union.ts(3,5): error TS18051: Type '["a", "x", "c"]' is not assignable to type 'TupleOf<"a" | "b" | "c">' + Type '"x"' at index 1 is not assignable to type '"b" | "c"' +tests/cases/compiler/self-types-tuple-from-union.ts(4,5): error TS18051: Type '["a", "b", "b"]' is not assignable to type 'TupleOf<"a" | "b" | "c">' + Type '"b"' at index 2 is not assignable to type '"c"' + + +==== tests/cases/compiler/self-types-tuple-from-union.ts (2 errors) ==== + let t0: TupleOf<"a" | "b" | "c"> = ["a", "b", "c"] as ["a", "b", "c"] + let t1: TupleOf<"a" | "b" | "c"> = ["c", "a", "b"] as ["c", "a", "b"] + let t2: TupleOf<"a" | "b" | "c"> = ["a", "x", "c"] as ["a", "x", "c"] + ~~ +!!! error TS18051: Type '["a", "x", "c"]' is not assignable to type 'TupleOf<"a" | "b" | "c">' +!!! error TS18051: Type '"x"' at index 1 is not assignable to type '"b" | "c"' + let t3: TupleOf<"a" | "b" | "c"> = ["a", "b", "b"] as ["a", "b", "b"] + ~~ +!!! error TS18051: Type '["a", "b", "b"]' is not assignable to type 'TupleOf<"a" | "b" | "c">' +!!! error TS18051: Type '"b"' at index 2 is not assignable to type '"c"' + + type TupleOf = + self extends unknown[] + ? number extends self["length"] + ? TupleError<`Type '${Print}' is not a tuple`, U, self> + : self["length"] extends ULength + ? ParseTupleOf extends infer E extends string + ? [E] extends [never] + ? self + : TupleError + : never + : TupleError<`Expected ${ULength} elements got ${self["length"]}`, U, self> + : TupleError<`Type '${Print}' is not a tuple`, U, self> + + type ParseTupleOf = + Self extends [] ? never : + Self extends [infer H, ...infer R] ? + H extends U + ? ParseTupleOf, R, [...I, 1]> + : `Type '${Print}' at index ${I["length"]} is not assignable to type '${Print}'` : + // TODO?: An intrinsic SubTypeError for using it here like + // Never<[ + // `Type '${Print}' at index ${I["length"]} is not assignable to type '${Print}'`]> + // ...SubTypeError + // ]> + never + + type TupleError = + Never<[ + `Type '${Print}' is not assignable to type 'TupleOf<${Print}>'`, + M + ]> + + type ULength = + [U] extends [never] ? A["length"] : + ULength, [...A, 1]> + + type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + + type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + + type UShifted = + Exclude> + + type UIsUnit = + [UShifted] extends [never] ? true : false + + export {} + \ No newline at end of file diff --git a/tests/baselines/reference/self-types-tuple-from-union.js b/tests/baselines/reference/self-types-tuple-from-union.js new file mode 100644 index 0000000000000..19eedd0d3062c --- /dev/null +++ b/tests/baselines/reference/self-types-tuple-from-union.js @@ -0,0 +1,68 @@ +//// [self-types-tuple-from-union.ts] +let t0: TupleOf<"a" | "b" | "c"> = ["a", "b", "c"] as ["a", "b", "c"] +let t1: TupleOf<"a" | "b" | "c"> = ["c", "a", "b"] as ["c", "a", "b"] +let t2: TupleOf<"a" | "b" | "c"> = ["a", "x", "c"] as ["a", "x", "c"] +let t3: TupleOf<"a" | "b" | "c"> = ["a", "b", "b"] as ["a", "b", "b"] + +type TupleOf = + self extends unknown[] + ? number extends self["length"] + ? TupleError<`Type '${Print}' is not a tuple`, U, self> + : self["length"] extends ULength + ? ParseTupleOf extends infer E extends string + ? [E] extends [never] + ? self + : TupleError + : never + : TupleError<`Expected ${ULength} elements got ${self["length"]}`, U, self> + : TupleError<`Type '${Print}' is not a tuple`, U, self> + +type ParseTupleOf = + Self extends [] ? never : + Self extends [infer H, ...infer R] ? + H extends U + ? ParseTupleOf, R, [...I, 1]> + : `Type '${Print}' at index ${I["length"]} is not assignable to type '${Print}'` : + // TODO?: An intrinsic SubTypeError for using it here like + // Never<[ + // `Type '${Print}' at index ${I["length"]} is not assignable to type '${Print}'`]> + // ...SubTypeError + // ]> + never + +type TupleError = + Never<[ + `Type '${Print}' is not assignable to type 'TupleOf<${Print}>'`, + M + ]> + +type ULength = + [U] extends [never] ? A["length"] : + ULength, [...A, 1]> + +type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + +type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + +type UShifted = + Exclude> + +type UIsUnit = + [UShifted] extends [never] ? true : false + +export {} + + +//// [self-types-tuple-from-union.js] +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var t0 = ["a", "b", "c"]; +var t1 = ["c", "a", "b"]; +var t2 = ["a", "x", "c"]; +var t3 = ["a", "b", "b"]; diff --git a/tests/baselines/reference/self-types-tuple-from-union.symbols b/tests/baselines/reference/self-types-tuple-from-union.symbols new file mode 100644 index 0000000000000..6e4396cee7799 --- /dev/null +++ b/tests/baselines/reference/self-types-tuple-from-union.symbols @@ -0,0 +1,186 @@ +=== tests/cases/compiler/self-types-tuple-from-union.ts === +let t0: TupleOf<"a" | "b" | "c"> = ["a", "b", "c"] as ["a", "b", "c"] +>t0 : Symbol(t0, Decl(self-types-tuple-from-union.ts, 0, 3)) +>TupleOf : Symbol(TupleOf, Decl(self-types-tuple-from-union.ts, 3, 69)) + +let t1: TupleOf<"a" | "b" | "c"> = ["c", "a", "b"] as ["c", "a", "b"] +>t1 : Symbol(t1, Decl(self-types-tuple-from-union.ts, 1, 3)) +>TupleOf : Symbol(TupleOf, Decl(self-types-tuple-from-union.ts, 3, 69)) + +let t2: TupleOf<"a" | "b" | "c"> = ["a", "x", "c"] as ["a", "x", "c"] +>t2 : Symbol(t2, Decl(self-types-tuple-from-union.ts, 2, 3)) +>TupleOf : Symbol(TupleOf, Decl(self-types-tuple-from-union.ts, 3, 69)) + +let t3: TupleOf<"a" | "b" | "c"> = ["a", "b", "b"] as ["a", "b", "b"] +>t3 : Symbol(t3, Decl(self-types-tuple-from-union.ts, 3, 3)) +>TupleOf : Symbol(TupleOf, Decl(self-types-tuple-from-union.ts, 3, 69)) + +type TupleOf = +>TupleOf : Symbol(TupleOf, Decl(self-types-tuple-from-union.ts, 3, 69)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 5, 13)) + + self extends unknown[] + ? number extends self["length"] + ? TupleError<`Type '${Print}' is not a tuple`, U, self> +>TupleError : Symbol(TupleError, Decl(self-types-tuple-from-union.ts, 29, 7)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 5, 13)) + + : self["length"] extends ULength +>ULength : Symbol(ULength, Decl(self-types-tuple-from-union.ts, 35, 4)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 5, 13)) + + ? ParseTupleOf extends infer E extends string +>ParseTupleOf : Symbol(ParseTupleOf, Decl(self-types-tuple-from-union.ts, 16, 65)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 5, 13)) +>E : Symbol(E, Decl(self-types-tuple-from-union.ts, 10, 49)) + + ? [E] extends [never] +>E : Symbol(E, Decl(self-types-tuple-from-union.ts, 10, 49)) + + ? self + : TupleError +>TupleError : Symbol(TupleError, Decl(self-types-tuple-from-union.ts, 29, 7)) +>E : Symbol(E, Decl(self-types-tuple-from-union.ts, 10, 49)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 5, 13)) + + : never + : TupleError<`Expected ${ULength} elements got ${self["length"]}`, U, self> +>TupleError : Symbol(TupleError, Decl(self-types-tuple-from-union.ts, 29, 7)) +>ULength : Symbol(ULength, Decl(self-types-tuple-from-union.ts, 35, 4)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 5, 13)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 5, 13)) + + : TupleError<`Type '${Print}' is not a tuple`, U, self> +>TupleError : Symbol(TupleError, Decl(self-types-tuple-from-union.ts, 29, 7)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 5, 13)) + +type ParseTupleOf = +>ParseTupleOf : Symbol(ParseTupleOf, Decl(self-types-tuple-from-union.ts, 16, 65)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 18, 18)) +>Self : Symbol(Self, Decl(self-types-tuple-from-union.ts, 18, 20)) +>I : Symbol(I, Decl(self-types-tuple-from-union.ts, 18, 26)) + + Self extends [] ? never : +>Self : Symbol(Self, Decl(self-types-tuple-from-union.ts, 18, 20)) + + Self extends [infer H, ...infer R] ? +>Self : Symbol(Self, Decl(self-types-tuple-from-union.ts, 18, 20)) +>H : Symbol(H, Decl(self-types-tuple-from-union.ts, 20, 21)) +>R : Symbol(R, Decl(self-types-tuple-from-union.ts, 20, 33)) + + H extends U +>H : Symbol(H, Decl(self-types-tuple-from-union.ts, 20, 21)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 18, 18)) + + ? ParseTupleOf, R, [...I, 1]> +>ParseTupleOf : Symbol(ParseTupleOf, Decl(self-types-tuple-from-union.ts, 16, 65)) +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 18, 18)) +>H : Symbol(H, Decl(self-types-tuple-from-union.ts, 20, 21)) +>R : Symbol(R, Decl(self-types-tuple-from-union.ts, 20, 33)) +>I : Symbol(I, Decl(self-types-tuple-from-union.ts, 18, 26)) + + : `Type '${Print}' at index ${I["length"]} is not assignable to type '${Print}'` : +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>H : Symbol(H, Decl(self-types-tuple-from-union.ts, 20, 21)) +>I : Symbol(I, Decl(self-types-tuple-from-union.ts, 18, 26)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 18, 18)) + + // TODO?: An intrinsic SubTypeError for using it here like + // Never<[ + // `Type '${Print}' at index ${I["length"]} is not assignable to type '${Print}'`]> + // ...SubTypeError + // ]> + never + +type TupleError = +>TupleError : Symbol(TupleError, Decl(self-types-tuple-from-union.ts, 29, 7)) +>M : Symbol(M, Decl(self-types-tuple-from-union.ts, 31, 16)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 31, 33)) +>Self : Symbol(Self, Decl(self-types-tuple-from-union.ts, 31, 36)) + + Never<[ +>Never : Symbol(Never, Decl(lib.es5.d.ts, --, --)) + + `Type '${Print}' is not assignable to type 'TupleOf<${Print}>'`, +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>Self : Symbol(Self, Decl(self-types-tuple-from-union.ts, 31, 36)) +>Print : Symbol(Print, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 31, 33)) + + M +>M : Symbol(M, Decl(self-types-tuple-from-union.ts, 31, 16)) + + ]> + +type ULength = +>ULength : Symbol(ULength, Decl(self-types-tuple-from-union.ts, 35, 4)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 37, 13)) +>A : Symbol(A, Decl(self-types-tuple-from-union.ts, 37, 15)) + + [U] extends [never] ? A["length"] : +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 37, 13)) +>A : Symbol(A, Decl(self-types-tuple-from-union.ts, 37, 15)) + + ULength, [...A, 1]> +>ULength : Symbol(ULength, Decl(self-types-tuple-from-union.ts, 35, 4)) +>UShifted : Symbol(UShifted, Decl(self-types-tuple-from-union.ts, 49, 11)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 37, 13)) +>A : Symbol(A, Decl(self-types-tuple-from-union.ts, 37, 15)) + +type UShift = +>UShift : Symbol(UShift, Decl(self-types-tuple-from-union.ts, 39, 33)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 41, 12)) + + UToIntersection void : never> extends (_: infer H) => void +>UToIntersection : Symbol(UToIntersection, Decl(self-types-tuple-from-union.ts, 44, 11)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 41, 12)) +>x : Symbol(x, Decl(self-types-tuple-from-union.ts, 42, 39)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 41, 12)) +>_ : Symbol(_, Decl(self-types-tuple-from-union.ts, 42, 71)) +>H : Symbol(H, Decl(self-types-tuple-from-union.ts, 42, 79)) + + ? H +>H : Symbol(H, Decl(self-types-tuple-from-union.ts, 42, 79)) + + : never + +type UToIntersection = +>UToIntersection : Symbol(UToIntersection, Decl(self-types-tuple-from-union.ts, 44, 11)) +>T : Symbol(T, Decl(self-types-tuple-from-union.ts, 46, 21)) + + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) +>T : Symbol(T, Decl(self-types-tuple-from-union.ts, 46, 21)) +>_ : Symbol(_, Decl(self-types-tuple-from-union.ts, 47, 24)) +>T : Symbol(T, Decl(self-types-tuple-from-union.ts, 46, 21)) +>_ : Symbol(_, Decl(self-types-tuple-from-union.ts, 47, 57)) +>I : Symbol(I, Decl(self-types-tuple-from-union.ts, 47, 65)) + + ? I +>I : Symbol(I, Decl(self-types-tuple-from-union.ts, 47, 65)) + + : never + +type UShifted = +>UShifted : Symbol(UShifted, Decl(self-types-tuple-from-union.ts, 49, 11)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 51, 14)) + + Exclude> +>Exclude : Symbol(Exclude, Decl(lib.es5.d.ts, --, --)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 51, 14)) +>UShift : Symbol(UShift, Decl(self-types-tuple-from-union.ts, 39, 33)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 51, 14)) + +type UIsUnit = +>UIsUnit : Symbol(UIsUnit, Decl(self-types-tuple-from-union.ts, 52, 23)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 54, 13)) + + [UShifted] extends [never] ? true : false +>UShifted : Symbol(UShifted, Decl(self-types-tuple-from-union.ts, 49, 11)) +>U : Symbol(U, Decl(self-types-tuple-from-union.ts, 54, 13)) + +export {} + diff --git a/tests/baselines/reference/self-types-tuple-from-union.types b/tests/baselines/reference/self-types-tuple-from-union.types new file mode 100644 index 0000000000000..ec81151dd923a --- /dev/null +++ b/tests/baselines/reference/self-types-tuple-from-union.types @@ -0,0 +1,111 @@ +=== tests/cases/compiler/self-types-tuple-from-union.ts === +let t0: TupleOf<"a" | "b" | "c"> = ["a", "b", "c"] as ["a", "b", "c"] +>t0 : TupleOf<"a" | "b" | "c"> +>["a", "b", "c"] as ["a", "b", "c"] : ["a", "b", "c"] +>["a", "b", "c"] : ["a", "b", "c"] +>"a" : "a" +>"b" : "b" +>"c" : "c" + +let t1: TupleOf<"a" | "b" | "c"> = ["c", "a", "b"] as ["c", "a", "b"] +>t1 : TupleOf<"a" | "b" | "c"> +>["c", "a", "b"] as ["c", "a", "b"] : ["c", "a", "b"] +>["c", "a", "b"] : ["c", "a", "b"] +>"c" : "c" +>"a" : "a" +>"b" : "b" + +let t2: TupleOf<"a" | "b" | "c"> = ["a", "x", "c"] as ["a", "x", "c"] +>t2 : TupleOf<"a" | "b" | "c"> +>["a", "x", "c"] as ["a", "x", "c"] : ["a", "x", "c"] +>["a", "x", "c"] : ["a", "x", "c"] +>"a" : "a" +>"x" : "x" +>"c" : "c" + +let t3: TupleOf<"a" | "b" | "c"> = ["a", "b", "b"] as ["a", "b", "b"] +>t3 : TupleOf<"a" | "b" | "c"> +>["a", "b", "b"] as ["a", "b", "b"] : ["a", "b", "b"] +>["a", "b", "b"] : ["a", "b", "b"] +>"a" : "a" +>"b" : "b" +>"b" : "b" + +type TupleOf = +>TupleOf : TupleOf + + self extends unknown[] + ? number extends self["length"] + ? TupleError<`Type '${Print}' is not a tuple`, U, self> + : self["length"] extends ULength + ? ParseTupleOf extends infer E extends string + ? [E] extends [never] + ? self + : TupleError + : never + : TupleError<`Expected ${ULength} elements got ${self["length"]}`, U, self> + : TupleError<`Type '${Print}' is not a tuple`, U, self> + +type ParseTupleOf = +>ParseTupleOf : ParseTupleOf + + Self extends [] ? never : + Self extends [infer H, ...infer R] ? + H extends U + ? ParseTupleOf, R, [...I, 1]> + : `Type '${Print}' at index ${I["length"]} is not assignable to type '${Print}'` : + // TODO?: An intrinsic SubTypeError for using it here like + // Never<[ + // `Type '${Print}' at index ${I["length"]} is not assignable to type '${Print}'`]> + // ...SubTypeError + // ]> + never + +type TupleError = +>TupleError : never + + Never<[ + `Type '${Print}' is not assignable to type 'TupleOf<${Print}>'`, + M + ]> + +type ULength = +>ULength : ULength + + [U] extends [never] ? A["length"] : + ULength, [...A, 1]> + +type UShift = +>UShift : UShift + + UToIntersection void : never> extends (_: infer H) => void +>x : U +>_ : H + + ? H + : never + +type UToIntersection = +>UToIntersection : UToIntersection + + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) +>_ : T +>_ : I + + ? I + : never + +type UShifted = +>UShifted : UShifted + + Exclude> + +type UIsUnit = +>UIsUnit : UIsUnit + + [UShifted] extends [never] ? true : false +>true : true +>false : false + +export {} + diff --git a/tests/baselines/reference/tsserver/moduleSpecifierCache/caches-importability-within-a-file.js b/tests/baselines/reference/tsserver/moduleSpecifierCache/caches-importability-within-a-file.js index 5200ac9388c56..d8f6d48b0fe68 100644 --- a/tests/baselines/reference/tsserver/moduleSpecifierCache/caches-importability-within-a-file.js +++ b/tests/baselines/reference/tsserver/moduleSpecifierCache/caches-importability-within-a-file.js @@ -735,6 +735,12 @@ Info 54 [00:01:54.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/tsserver/moduleSpecifierCache/caches-module-specifiers-within-a-file.js b/tests/baselines/reference/tsserver/moduleSpecifierCache/caches-module-specifiers-within-a-file.js index ec66b17c7a6ea..6b4c575719674 100644 --- a/tests/baselines/reference/tsserver/moduleSpecifierCache/caches-module-specifiers-within-a-file.js +++ b/tests/baselines/reference/tsserver/moduleSpecifierCache/caches-module-specifiers-within-a-file.js @@ -735,6 +735,12 @@ Info 54 [00:01:54.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/tsserver/moduleSpecifierCache/does-not-invalidate-the-cache-when-new-files-are-added.js b/tests/baselines/reference/tsserver/moduleSpecifierCache/does-not-invalidate-the-cache-when-new-files-are-added.js index 4807d83148642..e1064b89ef5f6 100644 --- a/tests/baselines/reference/tsserver/moduleSpecifierCache/does-not-invalidate-the-cache-when-new-files-are-added.js +++ b/tests/baselines/reference/tsserver/moduleSpecifierCache/does-not-invalidate-the-cache-when-new-files-are-added.js @@ -735,6 +735,12 @@ Info 54 [00:01:54.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-module-specifiers-when-changes-happen-in-contained-node_modules-directories.js b/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-module-specifiers-when-changes-happen-in-contained-node_modules-directories.js index c1d6ddb05ec82..acad06a4e8f9c 100644 --- a/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-module-specifiers-when-changes-happen-in-contained-node_modules-directories.js +++ b/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-module-specifiers-when-changes-happen-in-contained-node_modules-directories.js @@ -735,6 +735,12 @@ Info 54 [00:01:54.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-local-packageJson-changes.js b/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-local-packageJson-changes.js index 94a45050eb7b2..67e89474e3efd 100644 --- a/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-local-packageJson-changes.js +++ b/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-local-packageJson-changes.js @@ -735,6 +735,12 @@ Info 54 [00:01:54.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-module-resolution-settings-change.js b/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-module-resolution-settings-change.js index f7f1164c598de..e74844d861b65 100644 --- a/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-module-resolution-settings-change.js +++ b/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-module-resolution-settings-change.js @@ -735,6 +735,12 @@ Info 54 [00:01:54.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-symlinks-are-added-or-removed.js b/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-symlinks-are-added-or-removed.js index 2ecac84fc8683..a99716212918a 100644 --- a/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-symlinks-are-added-or-removed.js +++ b/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-symlinks-are-added-or-removed.js @@ -735,6 +735,12 @@ Info 54 [00:01:54.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-user-preferences-change.js b/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-user-preferences-change.js index 484aec97d6752..7a3bb3254afb7 100644 --- a/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-user-preferences-change.js +++ b/tests/baselines/reference/tsserver/moduleSpecifierCache/invalidates-the-cache-when-user-preferences-change.js @@ -735,6 +735,12 @@ Info 54 [00:01:54.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", @@ -1298,6 +1304,12 @@ Info 71 [00:02:11.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", @@ -1858,6 +1870,12 @@ Info 87 [00:02:27.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", diff --git a/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js b/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js index a5315f584b303..bd79a47a799b5 100644 --- a/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js +++ b/tests/baselines/reference/tsserver/plugins/getSupportedCodeFixes-can-be-proxied.js @@ -1468,6 +1468,7 @@ Info 32 [00:01:13.000] response: "18048", "18049", "18050", + "18051", "80005", "80003", "80008", @@ -2800,6 +2801,7 @@ Info 38 [00:01:19.000] response: "18048", "18049", "18050", + "18051", "80005", "80003", "80008", @@ -4044,6 +4046,7 @@ Info 40 [00:01:21.000] response: "18048", "18049", "18050", + "18051", "80005", "80003", "80008", diff --git a/tests/baselines/reference/tsserver/projects/tsconfig-script-block-support.js b/tests/baselines/reference/tsserver/projects/tsconfig-script-block-support.js index 9ae1c7589a77b..bac1d96cc52e5 100644 --- a/tests/baselines/reference/tsserver/projects/tsconfig-script-block-support.js +++ b/tests/baselines/reference/tsserver/projects/tsconfig-script-block-support.js @@ -546,6 +546,12 @@ Info 49 [00:01:28.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", @@ -1011,6 +1017,12 @@ Info 59 [00:01:44.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "string", "kind": "keyword", diff --git a/tests/cases/compiler/self-types-case-insensitive.ts b/tests/cases/compiler/self-types-case-insensitive.ts new file mode 100644 index 0000000000000..c7cd52acd3fbe --- /dev/null +++ b/tests/cases/compiler/self-types-case-insensitive.ts @@ -0,0 +1,35 @@ +type CaseInsensitive = + self extends string + ? Lowercase extends Lowercase + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'CaseInsensitive<${Print}>'`, + `Type 'Lowercase<${Print}>' is not assignable to 'Lowercase<${Print}>'`, + `Type '${Print>}' is not assignable to '${Print>}'` + ]> + : T + +declare const setHeader: + (key: CaseInsensitive<"Set-Cookie" | "Accept">, value: string) => void + +setHeader("Set-Cookie", "test") +setHeader("Accept", "test2") +setHeader("sEt-cOoKiE", "stop writing headers like this but ok") +setHeader("Acept", "nah this has a typo") + +// TODO?: the autocompletion doesn't work, although it could be doable by +// instantiating `self` with `unknown`, at least in this case. +// Or by an alternative definition... +// type CaseInsensitive = T | [existing-defintion] +// the autocompletion works now but the custom error message doesn't +// get shown + +type Headers = + Record, string> + +let headers: Headers = { + // TODO: this is not an excess property, should compile + "Set-Cookie": "test" +} + +export {} \ No newline at end of file diff --git a/tests/cases/compiler/self-types-color.ts b/tests/cases/compiler/self-types-color.ts new file mode 100644 index 0000000000000..0112c2cc3ffd7 --- /dev/null +++ b/tests/cases/compiler/self-types-color.ts @@ -0,0 +1,184 @@ +type Color = + self extends string + ? ParseColor extends infer R + ? R extends { error: infer E extends string } + ? Never<[`Type '${Print}' is not assignable to type 'Color'`, E]> + : R + : never + : string + +const t0: Color = 123 +const t1: Color = "hello" as string +const t2: Color = "#fff" +const t3: Color = "#ffz" +const t4: Color = "rgb(100, 1000, 100)" +const t5 = "#fff" satisfies Color +const t6 = "#ffz" satisfies Color +const t7 = "#fff" as Color +const t8 = "#ffz" as Color +const t9 = "this is fine" as Color +const t10 = 0 as Color + + +type ParseColor = + S.IsStringLiteral extends false ? { error: "Expected a string literal" } : + T extends NamedColor ? T : + T extends `#${string}` ? ParseHexColor : + T extends `rgb${string}` ? ParseRgbColor : + { error: "Expected it to start with '#' or 'rgb' or be a named color" } + + +type ParseHexColor> = + [I, C] extends [4, ""] | [7, ""] ? T : + I extends 0 | 1 | 2 | 3 | 4 | 5 | 6 + ? C extends (I extends 0 ? "#" : Hexadecimal) + ? ParseHexColor> + : { error: `Expected ${I extends 0 ? "#": "an hexadecimal character"} got '${S.Cast}' at column ${I}` } : + { error: `Unexpected character at ${N.Cast}` } + + +type Hexadecimal = + ( "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" + | "a" | "b" | "c" | "d" | "e"| "f" + ) extends infer X + ? X | Uppercase> + : never + +type ParseRgbColor = + T extends `rgb${infer S}` + ? S extends `(${infer S}` + ? ParseNumberLessThanOrEqual, 255> extends infer X + ? X extends { error: infer E } ? { error: `${S.Cast} for red` } : + X extends { rest: infer S } ? + S.TrimedL extends `,${infer S}` + ? ParseNumberLessThanOrEqual, 255> extends infer X + ? X extends { error: infer E } ? { error: `${S.Cast} for green` } : + X extends { rest: infer S } ? + S.TrimedL extends `,${infer S}` + ? ParseNumberLessThanOrEqual, 255> extends infer X + ? X extends { error: infer E } ? { error: `${S.Cast} for blue` } : + X extends { rest: infer S } ? + S.TrimedR extends `)` + ? T + : { error: "Expected ')' after blue value at the end" } : + never + : never + : { error: "Expected ',' after green value" } : + never + : never + : { error: "Expected ',' after red value" } : + never + : never + : { error: `Expected '(' got ${S.Cast>} after rgb` } + : { error: `Expected 'rgb' at the start` } + +type ParseNumberLessThanOrEqual, V = N["value" & keyof N]> = + N extends { error: unknown } ? N : + Ns.IsLessThanOrEqual extends true ? N : + { error: `Expected value from '0' to '255' got '${S.Cast}'` } + +type ParseNumber> = + D extends { value: infer Nh, rest: infer Sh } + ? ParseNumber extends infer X + ? X extends { value: infer Nt, rest: infer S } + ? { value: `${S.Cast}${S.Cast}`, rest: S } + : { value: Nh, rest: Sh } + : never + : D + +type ParseDigit = + T extends `${0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}${infer S}` + ? T extends `${infer V}${S}` + ? { value: `${V}`, rest: S } + : never + : { error: "Expected a number" } + +type NamedColor = + "black" | "silver" | "gray" | "white" | "maroon" | "red" | "purple" | "fuchsia" | "green" | "lime" | "olive" | "yellow" | "navy" | "blue" | "teal" | "aqua" | "aliceblue" | "antiquewhite" | "aqua" | "aquamarine" | "azure" | "beige" | "bisque" | "black" | "blanchedalmond" | "blue" | "blueviolet" | "brown" | "burlywood" | "cadetblue" | "chartreuse" | "chocolate" | "coral" | "cornflowerblue" | "cornsilk" | "crimson" | "cyan" | "darkblue" | "darkcyan" | "darkgoldenrod" | "darkgray" | "darkgreen" | "darkgrey" | "darkkhaki" | "darkmagenta" | "darkolivegreen" | "darkorange" | "darkorchid" | "darkred" | "darksalmon" | "darkseagreen" | "darkslateblue" | "darkslategray" | "darkslategrey" | "darkturquoise" | "darkviolet" | "deeppink" | "deepskyblue" | "dimgray" | "dimgrey" | "dodgerblue" | "firebrick" | "floralwhite" | "forestgreen" | "fuchsia" | "gainsboro" | "ghostwhite" | "gold" | "goldenrod" | "gray" | "green" | "greenyellow" | "grey" | "honeydew" | "hotpink" | "indianred" | "indigo" | "ivory" | "khaki" | "lavender" | "lavenderblush" | "lawngreen" | "lemonchiffon" | "lightblue" | "lightcoral" | "lightcyan" | "lightgoldenrodyellow" | "lightgray" | "lightgreen" | "lightgrey" | "lightpink" | "lightsalmon" | "lightseagreen" | "lightskyblue" | "lightslategray" | "lightslategrey" | "lightsteelblue" | "lightyellow" | "lime" | "limegreen" | "linen" | "magenta" | "maroon" | "mediumaquamarine" | "mediumblue" | "mediumorchid" | "mediumpurple" | "mediumseagreen" | "mediumslateblue" | "mediumspringgreen" | "mediumturquoise" | "mediumvioletred" | "midnightblue" | "mintcream" | "mistyrose" | "moccasin" | "navajowhite" | "navy" | "oldlace" | "olive" | "olivedrab" | "orange" | "orangered" | "orchid" | "palegoldenrod" | "palegreen" | "paleturquoise" | "palevioletred" | "papayawhip" | "peachpuff" | "peru" | "pink" | "plum" | "powderblue" | "purple" | "red" | "rosybrown" | "royalblue" | "saddlebrown" | "salmon" | "sandybrown" | "seagreen" | "seashell" | "sienna" | "silver" | "skyblue" | "slateblue" | "slategray" | "slategrey" | "snow" | "springgreen" | "steelblue" | "tan" | "teal" | "thistle" | "tomato" | "turquoise" | "violet" | "wheat" | "white" | "whitesmoke" | "yellow" | "yellowgreen" + +namespace S { + export type IsString = + T extends string ? true : false; + + export type IsStringLiteral = + IsString extends true + ? string extends T ? false : true + : false + + export type Cast = + A.Cast + + export type At = + Split extends { [_ in A.Cast]: infer X } + ? X + : "" + + export type Split = + T extends `${infer H}${infer T}` ? [H, ...Split] : + T extends "" ? [] : [T] + + export type TrimedL = + T extends ` ${infer T}` ? TrimedL : T + + export type TrimedR = + T extends `${infer T} ` ? TrimedL : T + + export type Length = + Split["length"] + + export type Shifted = + S extends `${infer _}${infer T}` ? T : never +} + +export namespace N { + export type Cast = A.Cast + + export type NaturalNumbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]; + export type WholeNumbers = [0, ...NaturalNumbers]; + export type WholeNumbersUnshifted = [-1, ...WholeNumbers]; + + export type Increment = A.Get + export type Decrement = A.Get +} + +export namespace L { + export type SlicedH = + N extends 0 ? [] : + A extends [infer H, ...infer T] ? [H, ...SlicedH>] : + never +} + +export namespace Nd { + export type IsLessThanOrEqual = + A extends 0 ? true : + B extends A.Get>, number> ? false : + true + + export type IsLessThan = + A extends B ? false : + IsLessThanOrEqual +} + +export namespace Ns { + export type ToN = + { [N in keyof N.WholeNumbers]: + T extends N ? N.WholeNumbers[N] : never + }[keyof N.WholeNumbers] + + export type TrimL = + T extends `0${infer T}` ? TrimL : T + + export type IsLessThanOrEqual<_A, _B, A = TrimL<_A>, B = TrimL<_B>> = + Nd.IsLessThan, S.Length> extends true ? true : + S.Length extends S.Length + ? Nd.IsLessThan>, ToN>> extends true ? true : + S.At extends S.At ? IsLessThanOrEqual, S.Shifted> : + false : + false +} + + +export namespace A { + export type Cast = T extends U ? T : U; + export type Get = K extends keyof T ? T[K] : never +} \ No newline at end of file diff --git a/tests/cases/compiler/self-types-exact-flat.ts b/tests/cases/compiler/self-types-exact-flat.ts new file mode 100644 index 0000000000000..4f5cd88e54f1c --- /dev/null +++ b/tests/cases/compiler/self-types-exact-flat.ts @@ -0,0 +1,82 @@ +declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void + +f(() => ({ + a: { + b: "b", + x: "x" + }, + c: 0, + y: 1 +})) + +let a0 = { a: { b: 1, c: "x", d: "y" } } +let t00: { a: { b: number } } = a0 +let t01: Exact<{ a: { b: number } }> = a0 + +let a1 = (x: { a: number, b: number }) => ({ x: 0, y: 2 }) +let t10: (x: { a: number, b: number, c: number }) => { x: number } = a1 +let t11: Exact<(x: { a: number, b: number, c: number }) => { x: number }> = a1 + +type Exact = + self extends T + ? ExactError extends infer E + ? [E] extends [never] + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'Exact<${Print}>`, + `Excess properties found at ${Join}` + ]> + : never + : T + +type ExactError = + A extends T + ? T extends unknown + ? A extends (...a: infer Aa) => infer Ar + ? T extends (...a: infer Ea) => infer Er + ? Prefix<".$parameters", ExactError> | Prefix<".$result", ExactError> + : never : + A extends object + ? T extends object + ? { [K in keyof A]: + K extends keyof T + ? Prefix<`.${PrintKey}`, ExactError> + : `.${PrintKey}` + }[A extends unknown[] ? number & keyof A : keyof A] + : never : + never + : never + : never + +type Join = + UIsUnit extends true ? `${And extends true ? "and " : ""}${T}` : + `${Cast, string | number>}, ${Join, true>}` + +type Prefix = + [B] extends [never] + ? B + : `${A & string}${B & string}` + +type PrintKey = + K extends symbol ? Print : K + +type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + +type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + +type UShifted = + Exclude> + +type UIsUnit = + [UShifted] extends [never] ? true : false + +type Cast = + T extends U ? T : U + +export {} \ No newline at end of file diff --git a/tests/cases/compiler/self-types-exact.ts b/tests/cases/compiler/self-types-exact.ts new file mode 100644 index 0000000000000..15a3c5e7ea881 --- /dev/null +++ b/tests/cases/compiler/self-types-exact.ts @@ -0,0 +1,36 @@ +declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void + +f(() => ({ + a: { + b: "b", + x: "x" + }, + c: 0, + y: 1 +})) + +type Exact = + _Exact + +// TODO: doesn't work if written as,,, +// type Exact = ... + +type _Exact = + A extends T + ? T extends unknown + ? A extends (...a: infer Aa) => infer Ar + ? T extends (...a: infer Ea) => infer Er + ? (...a: _Exact) => _Exact + : T : + A extends object + ? T extends object + ? { [K in keyof A]: + K extends keyof T ? _Exact : + Never<`Excess property '${K & string}' not allowed as the target is an exact type`> + } + : T : + T + : never + : T + +export {} \ No newline at end of file diff --git a/tests/cases/compiler/self-types-json-simple.ts b/tests/cases/compiler/self-types-json-simple.ts new file mode 100644 index 0000000000000..36e791409892c --- /dev/null +++ b/tests/cases/compiler/self-types-json-simple.ts @@ -0,0 +1,28 @@ +type Json = + | string + | number + | boolean + | null + | { toJSON: () => string } + | (self extends unknown[] ? Json[] : self extends (...a: never[]) => unknown ? never : { [_ in keyof self]: Json }) + | (self extends (...a: never[]) => unknown ? Never<`Type '${Print}' is not assignable to type 'Json'`> : never) + +interface Node { + children: Node[] + parent: Node +} +let someNode = {} as Node + +let t1: Json = someNode // TODO: this should probably compile +let t3: Json = () => "hello" +let t4: Json = { + x: () => "hello" +} +let t5: Json = { + toJSON: () => "hello" +} +let t6: Json = new Map() +let t7: Json = ["hello", undefined] +let t8: Json = ["hello", null] as [string, null] + +export {} diff --git a/tests/cases/compiler/self-types-json.ts b/tests/cases/compiler/self-types-json.ts new file mode 100644 index 0000000000000..44479276d4919 --- /dev/null +++ b/tests/cases/compiler/self-types-json.ts @@ -0,0 +1,74 @@ +interface Node { + children: Node[] + parent: Node +} +let someNode = {} as Node + +let t1: Json = someNode +let t2: Json<"AllowPossiblyCircular"> = someNode +let t3: Json = () => "hello" +let t4: Json = { + x: () => "hello" +} +let t5: Json = { + toJSON: () => "hello" +} +let t6: Json = new Map() // TODO: fourslash doesn't seem to include Map +let t7: Json = ["hello", undefined] +let t8: Json = ["hello", undefined] as [string, undefined] +let t9: Json<"AllowUndefined"> = ["hello", undefined] + +type Json = + JsonError extends infer E + ? [E] extends [never] + ? self + : Never<`Type '${Print}' is not assignable to type 'Json', as ${E & string}`> + : never + +type JsonError = + T extends (...a: never[]) => unknown + ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a function` : + T extends { toJSON: () => string } + ? never : + IsCircular extends true + ? "AllowPossiblyCircular" extends Flags + ? never + : `${IsTopLevel extends true ? "it " : ""}possibly has circular references` : + T extends object + ? UShift<{ [K in keyof T]: + JsonError extends infer E + ? [E] extends [never] + ? never + : `value at .${K extends symbol ? `(${Print})` : K} ${E & string}` + : never + }[T extends unknown[] ? number & keyof T : keyof T]> : + T extends undefined ? "AllowUndefined" extends Flags ? never : `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} undefined` : + T extends bigint ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a bigint` : + T extends symbol ? `${IsTopLevel extends true ? "it " : ""}${UIsUnit extends true ? "is" : "could be"} a symbol` : + never + +type IsCircular = + T extends Visited ? true : + T extends object + ? true extends { [K in keyof T]: IsCircular }[keyof T] + ? true + : false : + false + +type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + +type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + +type UShifted = + Exclude> + +type UIsUnit = + [UShifted] extends [never] ? true : false + +export {} diff --git a/tests/cases/compiler/self-types-keyof.ts b/tests/cases/compiler/self-types-keyof.ts new file mode 100644 index 0000000000000..f81875e4cd332 --- /dev/null +++ b/tests/cases/compiler/self-types-keyof.ts @@ -0,0 +1,20 @@ +// Implementing index types without index types + +type KeyOf = + self extends string | number | symbol + ? T extends { [_ in self]: unknown } + ? self + : Never<`Type '${Print}' can't be used to index type '${Print}'`> + : string | number | symbol + +let t0: KeyOf<{ a: number }> = "a" +let t1: KeyOf<{ a: number }> = "b" + +declare const get: + >(t: T, k: K) => + T extends { [_ in K]: infer X } ? X : never + +let t3: number = get({ a: 10 }, "a") +let t4 = get({ a: 10 }, "b") + +export {} diff --git a/tests/cases/compiler/self-types-mapped.ts b/tests/cases/compiler/self-types-mapped.ts new file mode 100644 index 0000000000000..6d696c8bfa0da --- /dev/null +++ b/tests/cases/compiler/self-types-mapped.ts @@ -0,0 +1,150 @@ +// Implementing mapped types without mapped types + +type User = + { name: string + , age: number + } + +type _Partial = Mapped}>`> +interface Mappers { _Partial: A[K & keyof A] | undefined } +// same as writing +// type _Partial = { [K in keyof T]: T[K] | undefined } + +let t00: _Partial = { + name: "foo", + age: undefined +} + +let t01: _Partial = { + name: 0, + age: undefined +} + +let t02: _Partial = { + age: undefined +} + +type _Omit = Mapped, "_Omit", T, `_Omit<${Print}, ${Print}>`> +interface Mappers { _Omit: A[K & keyof A] } +// same as writing +// type _Omit = { [K in Exclude]: T[K] } + +let t10: _Omit = { + name: "foo" +} + +let t11: _Omit = { + name: 0 +} + +let t12: _Omit = { +} + +type FlipValues = + Mapped}, ${Print}, ${Print}>`> +interface Mappers + { FlipValues: + A extends [infer T, infer K1, infer K2] + ? K extends K1 ? T[K2 & keyof T] : + K extends K2 ? T[K1 & keyof T] : + T[K & keyof T] + : never + } +// same as writing +// type FlipValues = +// { [K in keyof T]: +// K extends K1 ? T[K2] : +// K extends K2 ? T[K1] : +// T[K] +// } + + +let t30: FlipValues = { + name: "foo", + age: 0 +} + +let t31: FlipValues = { + name: 0, + age: "foo" +} + +let t32: FlipValues = { + name: 0 +} + +/** + * @param K key of new type + * @param F mapper identifier + * @param A extra argument to mapper + * @param N name of new type + */ +type Mapped = + MappedError extends infer E extends string | string[] + ? [E] extends [never] ? self : Never + : never + +type MappedError = + UShift< + K extends unknown + ? K extends keyof Self + ? Get, F> extends infer Fka // F + ? Self[K] extends Fka + ? never + : [ `Type '${Print}' is not assignable to type '${N & string}'` + , `Type '${Print}' is not assignable to type '${PrintMapped}'` + , `Types at property '${PrintKey}' are incompatible` + , `Type '${Print}' is not assignable to type '${Print}'` + ] + : never + : [ `Type '${Print}' is not assignable to type '${N & string}'` + , `Type '${Print}' is not assignable to type '${PrintMapped}'` + , `Property '${PrintKey}' is required in target type but missing in source type` + ] + : never + > + +interface Mappers {} + +type PrintMapped = + `{ ${Join< + K extends unknown + ? `${PrintKey}: ${Print, F>>};` + : never, + " " + >} }` + + +type Join = + UIsUnit extends true ? `${T}` : + `${Cast, string | number>}${D}${Join, D>}` + +type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + +type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + +type UShifted = + Exclude> + +type UIsUnit = + [UShifted] extends [never] ? true : false + +type Cast = + T extends U ? T : U + +type PrintKey = + K extends symbol ? Print : + K extends string ? K : + K extends number ? K : + never + +type Get = + K extends keyof T ? T[K] : never + +export {} \ No newline at end of file diff --git a/tests/cases/compiler/self-types-non-zero-number.ts b/tests/cases/compiler/self-types-non-zero-number.ts new file mode 100644 index 0000000000000..c85daf5d61f9b --- /dev/null +++ b/tests/cases/compiler/self-types-non-zero-number.ts @@ -0,0 +1,14 @@ +type NonZeroNumber = + self extends number + ? self extends 0 + ? Never<`Type '${Print}' is not assignable to type 'NonZeroNumber'`> + : self + : number + +const divide = (a: number, b: NonZeroNumber) => (a / (b as number)) as NonZeroNumber + +divide(1, 0) +divide(1, 1) +divide(1, "x") + +export {} \ No newline at end of file diff --git a/tests/cases/compiler/self-types-not.ts b/tests/cases/compiler/self-types-not.ts new file mode 100644 index 0000000000000..39cc8f5776601 --- /dev/null +++ b/tests/cases/compiler/self-types-not.ts @@ -0,0 +1,12 @@ +type Not = + self extends T + ? Never<`Type '${Print}' is not assignable to type 'Not<${Print}>'`> + : self + +const divide = (a: number, b: number & Not<0>) => a / b + +divide(1, 0) +divide(1, 1) +divide(1, "x") + +export {} \ No newline at end of file diff --git a/tests/cases/compiler/self-types-probability.ts b/tests/cases/compiler/self-types-probability.ts new file mode 100644 index 0000000000000..6fc5f025d30c5 --- /dev/null +++ b/tests/cases/compiler/self-types-probability.ts @@ -0,0 +1,36 @@ +let t0: Probability = 0.5 +let t1: Probability = 0 +let t2: Probability = 1 +let t3: Probability = 1.5 +let t4: Probability = -0.5 +let t5: Probability = 0 as number +let t6: number = 0.5 as Probability +let t7: Probability = t0 + t1 +let t8: number = t0 + t1 + +declare const f: (x: number) => void +f(t0) + +type F = T +type T0 = F + +// TODO: this should compile +type T1 = Assert + +type Probability = + self extends number + ? IsProbability extends true + ? self + : Never<`Type '${Print}' is not assignable to type 'Probability'`> + : number + +type IsProbability = + `${T}` extends `${infer H}${infer R}` + ? H extends "0" ? true : + H extends "1" ? R extends "" ? true : false : + false + : false + +type Assert = T + +export {} \ No newline at end of file diff --git a/tests/cases/compiler/self-types-ryan.ts b/tests/cases/compiler/self-types-ryan.ts new file mode 100644 index 0000000000000..51bedf4ae62ea --- /dev/null +++ b/tests/cases/compiler/self-types-ryan.ts @@ -0,0 +1,50 @@ +type CaseInsensitive = + self extends string + ? Lowercase extends Lowercase + ? self + : Never<[ + `Type '${Print}' is not assignable to type 'CaseInsensitive<${Print}>'`, + `Type 'Lowercase<${Print}>' is not assignable to 'Lowercase<${Print}>'`, + `Type '${Print>}' is not assignable to '${Print>}'` + ]> + : T + +type Box = { value: T }; +type Fooish = CaseInsensitive<"Foo">; +const x1: CaseInsensitive<"Foo"> = "FOO"; +const x2: Fooish = "FOO"; +const x3: Box> = { value: "FOO" }; +const x4: Box = { value: "FOO" }; + +type HeaderNames = CaseInsensitive<"Set-Cookie" | "Accept">; +declare const setHeader: (key: HeaderNames, value: string) => void +setHeader("Set-Cookie", "test") +setHeader("Accept", "test2") +setHeader("sEt-cOoKiE", "stop writing headers like this but ok") +setHeader("Acept", "nah this has a typo") + +type DistributeCaseInsensitive = T extends unknown ? CaseInsensitive : never; +let m: DistributeCaseInsensitive<"A" | "B"> = "a" + +type BarIfFoo = + T extends "foo" + ? CaseInsensitive<"bar"> + : never + +declare const f: + (x: T, y: BarIfFoo) => void + +f("foo", "BAR") +f("foo", "XYZ") + +type AnyString1 = self extends string ? T : never; +function foo1(a: CaseInsensitive) { + let m: AnyString1 = a; + let n: AnyString1 = {} as string; +} + +type AnyString2 = self extends string ? self : never; +function foo2(a: CaseInsensitive) { + let m: AnyString2 = a; // TODO?: this should probably compile + let n: AnyString2 = {} as string; +} \ No newline at end of file diff --git a/tests/cases/compiler/self-types-state-machine.ts b/tests/cases/compiler/self-types-state-machine.ts new file mode 100644 index 0000000000000..400208dc69666 --- /dev/null +++ b/tests/cases/compiler/self-types-state-machine.ts @@ -0,0 +1,20 @@ +type StateMachine = + { [S in keyof self]: { [E in keyof self[S]]: keyof self } } + +let trafficLights: StateMachine = { + off: { + ON: "red" + }, + red: { + TICK: "yellow", + OFF: "off" + }, + yellow: { + TICK: "green", + OFF: "off" + }, + green: { + TICK: "reddd", + OFF: "off" + } +} \ No newline at end of file diff --git a/tests/cases/compiler/self-types-string-literal.ts b/tests/cases/compiler/self-types-string-literal.ts new file mode 100644 index 0000000000000..26f7e756697de --- /dev/null +++ b/tests/cases/compiler/self-types-string-literal.ts @@ -0,0 +1,15 @@ +type StringLiteral = + self extends string + ? string extends self + ? Never<`Type '${Print}' is not assignable to type 'StringLiteral'`> + : self + : string + +let x: StringLiteral = "x" as "x" +let y: StringLiteral = "y" as string +let xx: { x: StringLiteral } = { x: "x" as "x" } +let yy: { y: StringLiteral } = { y: "y" as string } +let zs: StringLiteral[] = ["z0" as "z0", "z1" as string, "z2" as "z2"] +let a: StringLiteral = "a" as StringLiteral +let b: StringLiteral = "b" +let cs: StringLiteral[] = ["c0", "c1", "c2"] diff --git a/tests/cases/compiler/self-types-tuple-from-union.ts b/tests/cases/compiler/self-types-tuple-from-union.ts new file mode 100644 index 0000000000000..d40f3f3bce111 --- /dev/null +++ b/tests/cases/compiler/self-types-tuple-from-union.ts @@ -0,0 +1,58 @@ +let t0: TupleOf<"a" | "b" | "c"> = ["a", "b", "c"] as ["a", "b", "c"] +let t1: TupleOf<"a" | "b" | "c"> = ["c", "a", "b"] as ["c", "a", "b"] +let t2: TupleOf<"a" | "b" | "c"> = ["a", "x", "c"] as ["a", "x", "c"] +let t3: TupleOf<"a" | "b" | "c"> = ["a", "b", "b"] as ["a", "b", "b"] + +type TupleOf = + self extends unknown[] + ? number extends self["length"] + ? TupleError<`Type '${Print}' is not a tuple`, U, self> + : self["length"] extends ULength + ? ParseTupleOf extends infer E extends string + ? [E] extends [never] + ? self + : TupleError + : never + : TupleError<`Expected ${ULength} elements got ${self["length"]}`, U, self> + : TupleError<`Type '${Print}' is not a tuple`, U, self> + +type ParseTupleOf = + Self extends [] ? never : + Self extends [infer H, ...infer R] ? + H extends U + ? ParseTupleOf, R, [...I, 1]> + : `Type '${Print}' at index ${I["length"]} is not assignable to type '${Print}'` : + // TODO?: An intrinsic SubTypeError for using it here like + // Never<[ + // `Type '${Print}' at index ${I["length"]} is not assignable to type '${Print}'`]> + // ...SubTypeError + // ]> + never + +type TupleError = + Never<[ + `Type '${Print}' is not assignable to type 'TupleOf<${Print}>'`, + M + ]> + +type ULength = + [U] extends [never] ? A["length"] : + ULength, [...A, 1]> + +type UShift = + UToIntersection void : never> extends (_: infer H) => void + ? H + : never + +type UToIntersection = + (T extends unknown ? (_: T) => void : never) extends ((_: infer I) => void) + ? I + : never + +type UShifted = + Exclude> + +type UIsUnit = + [UShifted] extends [never] ? true : false + +export {}