From 188b9bb3e6b1fb01452e2cafb6b9ce44df6c0fd7 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Mon, 19 Dec 2022 19:27:26 +0000 Subject: [PATCH 01/30] use bigint for type flags --- Herebyfile.mjs | 2 +- src/compiler/checker.ts | 30 ++++---- src/compiler/debug.ts | 1 + src/compiler/tracing.ts | 2 +- src/compiler/types.ts | 159 ++++++++++++++++++++-------------------- src/tsconfig-base.json | 4 +- 6 files changed, 100 insertions(+), 98 deletions(-) diff --git a/Herebyfile.mjs b/Herebyfile.mjs index e047f31f22a64..3904239007b00 100644 --- a/Herebyfile.mjs +++ b/Herebyfile.mjs @@ -205,7 +205,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 09b9b57f41c3d..e75436f9a2e5d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -9474,7 +9474,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; @@ -9883,7 +9883,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) { @@ -15777,7 +15777,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)) { @@ -15945,7 +15945,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 ? @@ -16260,7 +16260,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 @@ -16562,7 +16562,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); } @@ -22514,7 +22514,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 { @@ -22779,7 +22779,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]); @@ -22855,8 +22855,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); } /** @@ -24205,7 +24205,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)) { @@ -25375,7 +25375,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 @@ -27291,7 +27291,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) || node.parent.kind === SyntaxKind.ExportSpecifier) || node.parent.kind === SyntaxKind.NonNullExpression || declaration.kind === SyntaxKind.VariableDeclaration && (declaration as VariableDeclaration).exclamationToken || @@ -33982,7 +33982,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) { @@ -35273,7 +35273,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() { diff --git a/src/compiler/debug.ts b/src/compiler/debug.ts index 9bd8471f531b5..15f086311d909 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/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/types.ts b/src/compiler/types.ts index 92ec847e19b3f..5e39706f60bac 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5682,96 +5682,97 @@ export interface NodeLinks { serializedTypes?: Map; // Collection of types serialized at this location } -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 + + /** @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.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; 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", From 5540ad561a2426dc7cf79bd837ecf14d9928c4a5 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Mon, 19 Dec 2022 19:59:21 +0000 Subject: [PATCH 02/30] self-type-checking types allow referencing an implict type parameter called "self" in type aliases, which gets instantiated with the type being related to when checking a type relation --- src/compiler/checker.ts | 133 ++++++++++--- src/compiler/factory/nodeFactory.ts | 1 + src/compiler/parser.ts | 2 + src/compiler/scanner.ts | 1 + src/compiler/transformers/ts.ts | 1 + src/compiler/types.ts | 7 +- src/compiler/utilities.ts | 2 + src/services/utilities.ts | 1 + .../compiler/self-types-case-insensitive.ts | 24 +++ tests/cases/compiler/self-types-color.ts | 184 ++++++++++++++++++ tests/cases/compiler/self-types-exact-flat.ts | 79 ++++++++ tests/cases/compiler/self-types-exact.ts | 30 +++ .../cases/compiler/self-types-json-simple.ts | 27 +++ tests/cases/compiler/self-types-json.ts | 74 +++++++ .../compiler/self-types-not-composition.ts | 17 ++ .../cases/compiler/self-types-probability.ts | 36 ++++ .../compiler/self-types-state-machine.ts | 20 ++ .../compiler/self-types-string-literal.ts | 15 ++ 18 files changed, 630 insertions(+), 24 deletions(-) create mode 100644 tests/cases/compiler/self-types-case-insensitive.ts create mode 100644 tests/cases/compiler/self-types-color.ts create mode 100644 tests/cases/compiler/self-types-exact-flat.ts create mode 100644 tests/cases/compiler/self-types-exact.ts create mode 100644 tests/cases/compiler/self-types-json-simple.ts create mode 100644 tests/cases/compiler/self-types-json.ts create mode 100644 tests/cases/compiler/self-types-not-composition.ts create mode 100644 tests/cases/compiler/self-types-probability.ts create mode 100644 tests/cases/compiler/self-types-state-machine.ts create mode 100644 tests/cases/compiler/self-types-string-literal.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e75436f9a2e5d..1cfbc6ea7c129 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6146,6 +6146,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); @@ -11259,6 +11262,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 @@ -11301,11 +11307,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(getSymbolOfNode(node as ClassLikeDeclaration | InterfaceDeclaration)).thisType; - return thisType ? append(outerAndOwnTypeParameters, thisType) : outerAndOwnTypeParameters; + + const selfType = + node.kind === SyntaxKind.TypeAliasDeclaration ? getSymbolLinks(node.symbol).selfType : undefined; + + const implicitTypeParameters = [ + ...(thisType ? [thisType] : []), + ...(selfType ? [selfType] : []) + ]; + + return concatenate(outerAndOwnTypeParameters, implicitTypeParameters); } case SyntaxKind.JSDocParameterTag: const paramSymbol = getParameterSymbolFromJSDoc(node as JSDocParameterTag); @@ -11710,9 +11727,16 @@ 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.flags |= TypeFlags.ContainsSelf + } + if (popTypeResolution()) { const typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); - if (typeParameters) { + if (typeParameters || containsSelfType) { // Initialize the instantiation cache for generic type aliases. The declared type corresponds to // an instantiation of the type alias with the type parameters supplied as type arguments. links.typeParameters = typeParameters; @@ -11837,6 +11861,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); @@ -14839,13 +14864,17 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getStringMappingType(symbol, typeArguments[0]); } const links = getSymbolLinks(symbol); - const typeParameters = links.typeParameters!; + 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 = typeParameters ? createTypeMapper(typeParameters, filledTypeArguments) : createTypeMapper([], []); + instantiation = instantiateTypeWithAlias(type, mapper, aliasSymbol, aliasTypeArguments) + if (type.flags & TypeFlags.ContainsSelf) { + instantiation.flags |= TypeFlags.ContainsSelf + } + links.instantiations!.set(id, instantiation); } return instantiation; } @@ -14869,19 +14898,23 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return errorType; } const type = getDeclaredTypeOfSymbol(symbol); - const typeParameters = getSymbolLinks(symbol).typeParameters; - if (typeParameters) { - const numTypeArguments = length(node.typeArguments); - const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); - if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { - error(node, - minTypeArgumentCount === typeParameters.length ? - Diagnostics.Generic_type_0_requires_1_type_argument_s : - Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, - symbolToString(symbol), - minTypeArgumentCount, - typeParameters.length); - return errorType; + const links = getSymbolLinks(symbol) + const typeParameters = links.typeParameters; + const selfType = links.selfType + if (typeParameters || selfType) { + if (typeParameters) { + const numTypeArguments = length(node.typeArguments); + const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); + if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { + error(node, + minTypeArgumentCount === typeParameters.length ? + Diagnostics.Generic_type_0_requires_1_type_argument_s : + Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, + symbolToString(symbol), + minTypeArgumentCount, + typeParameters.length); + return errorType; + } } // We refrain from associating a local type alias with an instantiation of a top-level type alias // because the local alias may end up being referenced in an inferred return type where it is not @@ -17921,6 +17954,27 @@ 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 = createTypeParameter() as TypeParameter & IntrinsicType + localSelfType.intrinsicName = "self" + localSelfType.flags |= TypeFlags.Self + typeAliasLinks.selfType = localSelfType + + links.resolvedType = localSelfType + return links.resolvedType + } + function getTypeFromRestTypeNode(node: RestTypeNode | NamedTupleMember) { return getTypeFromTypeNode(getArrayElementTypeNode(node.type) || node.type); } @@ -17983,6 +18037,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: @@ -19562,7 +19618,17 @@ 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 { + if (!(target.flags & TypeFlags.ContainsSelf && source.flags & TypeFlags.ContainsSelf)) { + if (target.flags & TypeFlags.ContainsSelf) { + let targetSelfType = getSymbolLinks(target.aliasSymbol!).selfType! + target = instantiateType(target, makeUnaryTypeMapper(targetSelfType, source)); + } + if (source.flags & TypeFlags.ContainsSelf) { + let sourceSelfType = getSymbolLinks(source.aliasSymbol!).selfType! + source = instantiateType(source, makeUnaryTypeMapper(sourceSelfType, target)); + } + } const s = source.flags; const t = target.flags; if (t & TypeFlags.AnyOrUnknown || s & TypeFlags.Never || source === wildcardType) return true; @@ -19606,6 +19672,16 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isTypeRelatedTo(source: Type, target: Type, relation: Map) { + if (!(target.flags & TypeFlags.ContainsSelf && source.flags & TypeFlags.ContainsSelf)) { + if (target.flags & TypeFlags.ContainsSelf) { + let targetSelfType = getSymbolLinks(target.aliasSymbol!).selfType! + target = instantiateType(target, makeUnaryTypeMapper(targetSelfType, source)); + } + if (source.flags & TypeFlags.ContainsSelf) { + let sourceSelfType = getSymbolLinks(source.aliasSymbol!).selfType! + source = instantiateType(source, makeUnaryTypeMapper(sourceSelfType, target)); + } + } if (isFreshLiteralType(source)) { source = (source as FreshableType).regularType; } @@ -20027,6 +20103,16 @@ 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 { + if (!(originalTarget.flags & TypeFlags.ContainsSelf && originalSource.flags & TypeFlags.ContainsSelf)) { + if (originalTarget.flags & TypeFlags.ContainsSelf) { + let targetSelfType = getSymbolLinks(originalTarget.aliasSymbol!).selfType! + originalTarget = instantiateType(originalTarget, makeUnaryTypeMapper(targetSelfType, originalSource)); + } + if (originalSource.flags & TypeFlags.ContainsSelf) { + let sourceSelfType = getSymbolLinks(originalSource.aliasSymbol!).selfType! + originalSource = instantiateType(originalSource, makeUnaryTypeMapper(sourceSelfType, 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) { @@ -23334,7 +23420,8 @@ 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.ContainsSelf; if (type.flags & TypeFlags.ObjectFlagsType) { (type as ObjectFlagsType).objectFlags |= ObjectFlags.CouldContainTypeVariablesComputed | (result ? ObjectFlags.CouldContainTypeVariables : 0); } @@ -23342,7 +23429,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")); } diff --git a/src/compiler/factory/nodeFactory.ts b/src/compiler/factory/nodeFactory.ts index 4e872d7babb73..585a5d6db1f29 100644 --- a/src/compiler/factory/nodeFactory.ts +++ b/src/compiler/factory/nodeFactory.ts @@ -1513,6 +1513,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 f1f8bd002e875..b98093d62f56e 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4465,6 +4465,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: @@ -4540,6 +4541,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/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 5e39706f60bac..b43b6d33b0b59 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -201,6 +201,7 @@ export const enum SyntaxKind { ObjectKeyword, SatisfiesKeyword, SetKeyword, + SelfKeyword, StringKeyword, SymbolKeyword, TypeKeyword, @@ -630,6 +631,7 @@ export type KeywordSyntaxKind = | SyntaxKind.ReturnKeyword | SyntaxKind.SatisfiesKeyword | SyntaxKind.SetKeyword + | SyntaxKind.SelfKeyword | SyntaxKind.StaticKeyword | SyntaxKind.StringKeyword | SyntaxKind.SuperKeyword @@ -681,6 +683,7 @@ export type KeywordTypeSyntaxKind = | SyntaxKind.SymbolKeyword | SyntaxKind.UndefinedKeyword | SyntaxKind.UnknownKeyword + | SyntaxKind.SelfKeyword | SyntaxKind.VoidKeyword ; @@ -5480,6 +5483,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 @@ -5713,7 +5717,8 @@ export const TypeFlags = new class TypeFlags { NonPrimitive = 1n << 26n // intrinsic object type TemplateLiteral = 1n << 27n // Template literal type StringMapping = 1n << 28n // Uppercase/Lowercase type - + Self = 1n << 29n + ContainsSelf = 1n << 30n /** @internal */ AnyOrUnknown = this.Any | this.Unknown /** @internal */ diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8de47c348430e..fd5d2ea07eb4a 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -1975,6 +1975,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; @@ -6942,6 +6943,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/services/utilities.ts b/src/services/utilities.ts index a5e151ac7ab1a..d5a2ca66528de 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/tests/cases/compiler/self-types-case-insensitive.ts b/tests/cases/compiler/self-types-case-insensitive.ts new file mode 100644 index 0000000000000..c8f490593373f --- /dev/null +++ b/tests/cases/compiler/self-types-case-insensitive.ts @@ -0,0 +1,24 @@ +type CaseInsensitive = + self extends string + ? Lowercase extends Lowercase + ? self + : never + : 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") + +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..a8dbd48167507 --- /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 } + ? `Error: ${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 +} + + +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..5daa956d8b86b --- /dev/null +++ b/tests/cases/compiler/self-types-exact-flat.ts @@ -0,0 +1,79 @@ +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 + : `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 ? "[unprintabe-symbol]" : 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..dbff7296ecf19 --- /dev/null +++ b/tests/cases/compiler/self-types-exact.ts @@ -0,0 +1,30 @@ +declare const f: (x: Exact<() => { a: { b: string }, c: number }>) => void + +f(() => ({ + a: { + b: "b", + x: "x" + }, + c: 0, + y: 1 +})) + +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 : + `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..8c22447b473b7 --- /dev/null +++ b/tests/cases/compiler/self-types-json-simple.ts @@ -0,0 +1,27 @@ +type Json = + | string + | number + | boolean + | null + | { toJSON: () => string } + | (self extends unknown[] ? Json[] : self extends (...a: never[]) => unknown ? never : { [_ in keyof self]: Json }) + +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..d8231c0f16e4d --- /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() +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 + : `Error: ${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 ? "[unprintabe-symbol]" : 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-not-composition.ts b/tests/cases/compiler/self-types-not-composition.ts new file mode 100644 index 0000000000000..86c5d60fcc798 --- /dev/null +++ b/tests/cases/compiler/self-types-not-composition.ts @@ -0,0 +1,17 @@ +type Not = + self extends T + ? never + : self + +const divide = (a: number, b: number & Not<0>) => a / b +// This doesn't work because currently the compiler assumes that +// if a type A is a subtype of B then type A will be a subtype of B & C for all A, B and C. +// But this is not true if C is a type like the above `Not` type. +// TODO: change intersection types to not make this assumption if any of the consituents +// have the ContainsSelf flag + +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..b326ebac1c043 --- /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 + : 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-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..2a6c9de0f56c5 --- /dev/null +++ b/tests/cases/compiler/self-types-string-literal.ts @@ -0,0 +1,15 @@ +type StringLiteral = + self extends string + ? string extends self + ? "Error: Not a string literal" + : 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"] From 34c8a80632d3e8ab1f84be9f3ef95c588ee9465d Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Mon, 19 Dec 2022 20:01:18 +0000 Subject: [PATCH 03/30] add `NeverWithError` and `Print` type constructs --- src/compiler/checker.ts | 281 +++++++++++++----- src/compiler/diagnosticMessages.json | 4 + src/compiler/types.ts | 15 +- src/harness/fourslashInterfaceImpl.ts | 3 + src/lib/es5.d.ts | 11 + .../compiler/self-types-case-insensitive.ts | 6 +- tests/cases/compiler/self-types-color.ts | 2 +- tests/cases/compiler/self-types-exact-flat.ts | 7 +- tests/cases/compiler/self-types-exact.ts | 2 +- .../cases/compiler/self-types-json-simple.ts | 1 + tests/cases/compiler/self-types-json.ts | 4 +- .../compiler/self-types-not-composition.ts | 2 +- tests/cases/compiler/self-types-not.ts | 14 + .../cases/compiler/self-types-probability.ts | 2 +- .../compiler/self-types-string-literal.ts | 2 +- 15 files changed, 275 insertions(+), 81 deletions(-) create mode 100644 tests/cases/compiler/self-types-not.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1cfbc6ea7c129..bd5e5f8d011af 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1010,6 +1010,8 @@ import { WideningContext, WithStatement, YieldExpression, + NeverWithErrorType, + PrintType, } from "./_namespaces/ts"; import * as performance from "./_namespaces/ts.performance"; import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers"; @@ -1277,14 +1279,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 })); function SymbolLinks(this: SymbolLinks) { @@ -1805,6 +1811,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); @@ -6338,8 +6346,43 @@ 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]; + console.log("template before") + console.log(JSON.stringify(texts)) + console.log(JSON.stringify(types.map(t => typeToString(t)))) + + 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;) { + let 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++; + } + console.log("template after") + console.log(JSON.stringify(texts)) + console.log(JSON.stringify(types.map(t => typeToString(t)))) + + 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( @@ -6352,6 +6395,9 @@ 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) { + 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); @@ -13340,7 +13386,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; } @@ -13453,6 +13499,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, @@ -14860,9 +14909,22 @@ 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); @@ -15913,7 +15975,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 || @@ -15991,7 +16053,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { orderedRemoveItemAt(typeSet, missingIndex); } } - 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) { @@ -16162,7 +16224,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 || @@ -16325,7 +16387,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 || @@ -16785,6 +16847,46 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return type; } + 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, undefined, + isTypeSubtypeOf(getStringLiteralType("InTypeAlias"), printType.flagType) + ? TypeFormatFlags.InTypeAlias + : TypeFormatFlags.None + )) + + 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, @@ -17038,7 +17140,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 { @@ -17069,7 +17172,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 { @@ -18636,6 +18739,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); @@ -18658,6 +18767,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } return newBaseType.flags & TypeFlags.TypeVariable ? getSubstitutionType(newBaseType, newConstraint) : getIntersectionType([newConstraint, newBaseType]); } + if (flags & TypeFlags.NeverWithError) { + return createNeverWithErrorType(instantiateType((type as NeverWithErrorType).errorType, mapper)) + } return type; } @@ -19987,62 +20099,86 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const [sourceType, targetType] = getTypeNamesForErrorDisplay(source, target); 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.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 - ); + + if (target.flags & TypeFlags.NeverWithError) { + const errorType = (target as NeverWithErrorType).errorType + const errorsType = (isTypeSubtypeOf(errorType, stringType) ? createTupleType([errorType]) : errorType) + if (!isTupleType(errorsType)) return reportNonCustom() + + 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, + typeToString(errorTypes.pop()!) + .slice(1,-1) + .replace(/\\"/g, '"') + .replace(/\\'/g, "'") + .replace(/\\\\/g, "\\") + .replace(/\\n/g, "\n") + ) } + return } + return reportNonCustom() - if (!message) { - if (relation === comparableRelation) { - message = Diagnostics.Type_0_is_not_comparable_to_type_1; + function reportNonCustom() { + if (isLiteralType(source) && !typeCouldHaveTopLevelSingletonTypes(target)) { + generalizedSource = getBaseTypeOfLiteralType(source); + Debug.assert(!isTypeAssignableTo(generalizedSource, target), "generalized source shouldn't be assignable"); + generalizedSourceType = getTypeNameForErrorDisplay(generalizedSource); } - 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; + + 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) { @@ -22734,7 +22870,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 : @@ -23421,7 +23557,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { 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.ContainsSelf; + type.flags & TypeFlags.ContainsSelf || + type.flags & TypeFlags.NeverWithError && couldContainTypeVariables((type as NeverWithErrorType).errorType)); if (type.flags & TypeFlags.ObjectFlagsType) { (type as ObjectFlagsType).objectFlags |= ObjectFlags.CouldContainTypeVariablesComputed | (result ? ObjectFlags.CouldContainTypeVariables : 0); } @@ -23678,7 +23815,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) { @@ -23966,6 +24103,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 @@ -24511,7 +24652,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) { @@ -25048,7 +25189,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)) { @@ -25472,10 +25613,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); } @@ -31732,7 +31873,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 = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping); + const hasPrimitiveContextualType = maybeTypeOfKind(contextualType, TypeFlags.Primitive | TypeFlags.Index | TypeFlags.TemplateLiteral | TypeFlags.StringMapping | TypeFlags.Print); types.push(hasPrimitiveContextualType ? getRegularTypeOfLiteralType(argType) : getWidenedLiteralType(argType)); flags.push(ElementFlags.Required); } @@ -36200,7 +36341,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) || diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index e146cce88c8cb..6d2f808653e1c 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -7548,5 +7548,9 @@ "The value '{0}' cannot be used here.": { "category": "Error", "code": 18050 + }, + "{0}": { + "category": "Error", + "code": 18051 } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index b43b6d33b0b59..bcb91fcf8e851 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5719,6 +5719,9 @@ export const TypeFlags = new class TypeFlags { StringMapping = 1n << 28n // Uppercase/Lowercase type Self = 1n << 29n ContainsSelf = 1n << 30n + NeverWithError = 1n << 31n + Print = 1n << 32n + /** @internal */ AnyOrUnknown = this.Any | this.Unknown /** @internal */ @@ -6285,7 +6288,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 @@ -6298,6 +6300,17 @@ export interface SubstitutionType extends InstantiableType { constraint: Type; // Constraint that target type is known to satisfy } +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, diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index af1044d6fee6b..bf6144168b4f3 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1188,6 +1188,8 @@ export namespace Completion { typeEntry("Lowercase"), typeEntry("Capitalize"), typeEntry("Uncapitalize"), + typeEntry("Never"), + typeEntry("Print"), interfaceEntry("ThisType"), varEntry("ArrayBuffer"), interfaceEntry("ArrayBufferTypes"), @@ -1215,6 +1217,7 @@ export namespace Completion { varEntry("Float64Array"), interfaceEntry("Float64ArrayConstructor"), moduleEntry("Intl"), + varEntry("Map") ]; export const globalThisEntry: ExpectedCompletionEntry = { diff --git a/src/lib/es5.d.ts b/src/lib/es5.d.ts index 9ed6d1c8a0c56..87e1fd87b5e8a 100644 --- a/src/lib/es5.d.ts +++ b/src/lib/es5.d.ts @@ -1631,6 +1631,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/tests/cases/compiler/self-types-case-insensitive.ts b/tests/cases/compiler/self-types-case-insensitive.ts index c8f490593373f..4f0305f64ea08 100644 --- a/tests/cases/compiler/self-types-case-insensitive.ts +++ b/tests/cases/compiler/self-types-case-insensitive.ts @@ -2,7 +2,11 @@ type CaseInsensitive = self extends string ? Lowercase extends Lowercase ? self - : never + : 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: diff --git a/tests/cases/compiler/self-types-color.ts b/tests/cases/compiler/self-types-color.ts index a8dbd48167507..8821cc6d2e0df 100644 --- a/tests/cases/compiler/self-types-color.ts +++ b/tests/cases/compiler/self-types-color.ts @@ -2,7 +2,7 @@ type 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 diff --git a/tests/cases/compiler/self-types-exact-flat.ts b/tests/cases/compiler/self-types-exact-flat.ts index 5daa956d8b86b..4f5cd88e54f1c 100644 --- a/tests/cases/compiler/self-types-exact-flat.ts +++ b/tests/cases/compiler/self-types-exact-flat.ts @@ -22,7 +22,10 @@ type Exact = ? ExactError extends infer E ? [E] extends [never] ? self - : `Excess properties found at ${Join}` + : Never<[ + `Type '${Print}' is not assignable to type 'Exact<${Print}>`, + `Excess properties found at ${Join}` + ]> : never : T @@ -55,7 +58,7 @@ type Prefix = : `${A & string}${B & string}` type PrintKey = - K extends symbol ? "[unprintabe-symbol]" : K + K extends symbol ? Print : K type UShift = UToIntersection void : never> extends (_: infer H) => void diff --git a/tests/cases/compiler/self-types-exact.ts b/tests/cases/compiler/self-types-exact.ts index dbff7296ecf19..5b4050fa6e7d2 100644 --- a/tests/cases/compiler/self-types-exact.ts +++ b/tests/cases/compiler/self-types-exact.ts @@ -20,7 +20,7 @@ type Exact = ? T extends object ? { [K in keyof A]: K extends keyof T ? Exact : - `Excess property '${K & string}' not allowed as the target is an exact type` + Never<`Excess property '${K & string}' not allowed as the target is an exact type`> } : T : T diff --git a/tests/cases/compiler/self-types-json-simple.ts b/tests/cases/compiler/self-types-json-simple.ts index 8c22447b473b7..36e791409892c 100644 --- a/tests/cases/compiler/self-types-json-simple.ts +++ b/tests/cases/compiler/self-types-json-simple.ts @@ -5,6 +5,7 @@ type Json = | 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[] diff --git a/tests/cases/compiler/self-types-json.ts b/tests/cases/compiler/self-types-json.ts index d8231c0f16e4d..253c3a40390a4 100644 --- a/tests/cases/compiler/self-types-json.ts +++ b/tests/cases/compiler/self-types-json.ts @@ -22,7 +22,7 @@ type Json = JsonError extends infer E ? [E] extends [never] ? self - : `Error: ${E & string}` + : Never<`Type '${Print}' is not assignable to type 'Json', as ${E & string}`> : never type JsonError = @@ -39,7 +39,7 @@ type JsonError = JsonError extends infer E ? [E] extends [never] ? never - : `value at .${K extends symbol ? "[unprintabe-symbol]" : K} ${E & string}` + : `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` : diff --git a/tests/cases/compiler/self-types-not-composition.ts b/tests/cases/compiler/self-types-not-composition.ts index 86c5d60fcc798..50eede6346ce2 100644 --- a/tests/cases/compiler/self-types-not-composition.ts +++ b/tests/cases/compiler/self-types-not-composition.ts @@ -1,6 +1,6 @@ type Not = self extends T - ? never + ? Never<`Type '${Print}' is not assignable to type 'Not<${Print}>'`> : self const divide = (a: number, b: number & Not<0>) => a / b diff --git a/tests/cases/compiler/self-types-not.ts b/tests/cases/compiler/self-types-not.ts new file mode 100644 index 0000000000000..c85daf5d61f9b --- /dev/null +++ b/tests/cases/compiler/self-types-not.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-probability.ts b/tests/cases/compiler/self-types-probability.ts index b326ebac1c043..6fc5f025d30c5 100644 --- a/tests/cases/compiler/self-types-probability.ts +++ b/tests/cases/compiler/self-types-probability.ts @@ -21,7 +21,7 @@ type Probability = self extends number ? IsProbability extends true ? self - : never + : Never<`Type '${Print}' is not assignable to type 'Probability'`> : number type IsProbability = diff --git a/tests/cases/compiler/self-types-string-literal.ts b/tests/cases/compiler/self-types-string-literal.ts index 2a6c9de0f56c5..26f7e756697de 100644 --- a/tests/cases/compiler/self-types-string-literal.ts +++ b/tests/cases/compiler/self-types-string-literal.ts @@ -1,7 +1,7 @@ type StringLiteral = self extends string ? string extends self - ? "Error: Not a string literal" + ? Never<`Type '${Print}' is not assignable to type 'StringLiteral'`> : self : string From c4d98c3339be94349f738e6f2978ab9981e0dcd6 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Tue, 27 Dec 2022 21:35:33 +0000 Subject: [PATCH 04/30] fix bad comment --- tests/cases/compiler/self-types-not-composition.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/cases/compiler/self-types-not-composition.ts b/tests/cases/compiler/self-types-not-composition.ts index 50eede6346ce2..5f241c38f4db9 100644 --- a/tests/cases/compiler/self-types-not-composition.ts +++ b/tests/cases/compiler/self-types-not-composition.ts @@ -4,13 +4,8 @@ type Not = : self const divide = (a: number, b: number & Not<0>) => a / b -// This doesn't work because currently the compiler assumes that -// if a type A is a subtype of B then type A will be a subtype of B & C for all A, B and C. -// But this is not true if C is a type like the above `Not` type. -// TODO: change intersection types to not make this assumption if any of the consituents -// have the ContainsSelf flag -divide(1, 0) +divide(1, 0) // TODO: shouldn't compile divide(1, 1) divide(1, "x") From 78d74a9ad3bf491c6ed88e32c39a3c3aabf2c481 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Tue, 3 Jan 2023 19:56:56 +0000 Subject: [PATCH 05/30] add new tests --- tests/cases/compiler/self-types-keyof.ts | 20 +++ tests/cases/compiler/self-types-mapped.ts | 150 ++++++++++++++++++ .../compiler/self-types-tuple-from-union.ts | 58 +++++++ 3 files changed, 228 insertions(+) create mode 100644 tests/cases/compiler/self-types-keyof.ts create mode 100644 tests/cases/compiler/self-types-mapped.ts create mode 100644 tests/cases/compiler/self-types-tuple-from-union.ts diff --git a/tests/cases/compiler/self-types-keyof.ts b/tests/cases/compiler/self-types-keyof.ts new file mode 100644 index 0000000000000..d0b784f714e95 --- /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" as "a") +// TODO?: this should compile + +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-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 {} From f3dc6f5bc96d8ec8c115e0d7982e6e39b63fcf8b Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Tue, 3 Jan 2023 19:57:32 +0000 Subject: [PATCH 06/30] make minor changes to some tests --- .../cases/compiler/self-types-case-insensitive.ts | 7 +++++++ tests/cases/compiler/self-types-color.ts | 2 +- tests/cases/compiler/self-types-non-zero-number.ts | 14 ++++++++++++++ tests/cases/compiler/self-types-not-composition.ts | 12 ------------ tests/cases/compiler/self-types-not.ts | 14 ++++++-------- 5 files changed, 28 insertions(+), 21 deletions(-) create mode 100644 tests/cases/compiler/self-types-non-zero-number.ts delete mode 100644 tests/cases/compiler/self-types-not-composition.ts diff --git a/tests/cases/compiler/self-types-case-insensitive.ts b/tests/cases/compiler/self-types-case-insensitive.ts index 4f0305f64ea08..c7cd52acd3fbe 100644 --- a/tests/cases/compiler/self-types-case-insensitive.ts +++ b/tests/cases/compiler/self-types-case-insensitive.ts @@ -17,6 +17,13 @@ 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> diff --git a/tests/cases/compiler/self-types-color.ts b/tests/cases/compiler/self-types-color.ts index 8821cc6d2e0df..0112c2cc3ffd7 100644 --- a/tests/cases/compiler/self-types-color.ts +++ b/tests/cases/compiler/self-types-color.ts @@ -178,7 +178,7 @@ export namespace Ns { } -namespace A { +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-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-composition.ts b/tests/cases/compiler/self-types-not-composition.ts deleted file mode 100644 index 5f241c38f4db9..0000000000000 --- a/tests/cases/compiler/self-types-not-composition.ts +++ /dev/null @@ -1,12 +0,0 @@ -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) // TODO: shouldn't compile -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 index c85daf5d61f9b..5f241c38f4db9 100644 --- a/tests/cases/compiler/self-types-not.ts +++ b/tests/cases/compiler/self-types-not.ts @@ -1,13 +1,11 @@ -type NonZeroNumber = - self extends number - ? self extends 0 - ? Never<`Type '${Print}' is not assignable to type 'NonZeroNumber'`> - : self - : number +type Not = + self extends T + ? Never<`Type '${Print}' is not assignable to type 'Not<${Print}>'`> + : self -const divide = (a: number, b: NonZeroNumber) => (a / (b as number)) as NonZeroNumber +const divide = (a: number, b: number & Not<0>) => a / b -divide(1, 0) +divide(1, 0) // TODO: shouldn't compile divide(1, 1) divide(1, "x") From ff005035abd47a775cffead6555c099c4ab582f5 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Tue, 3 Jan 2023 20:36:15 +0000 Subject: [PATCH 07/30] accept new baselines --- .../self-types-case-insensitive.errors.txt | 50 ++ .../reference/self-types-case-insensitive.js | 48 ++ .../self-types-case-insensitive.symbols | 80 ++ .../self-types-case-insensitive.types | 68 ++ .../reference/self-types-color.errors.txt | 213 ++++++ tests/baselines/reference/self-types-color.js | 200 +++++ .../reference/self-types-color.symbols | 713 ++++++++++++++++++ .../reference/self-types-color.types | 424 +++++++++++ .../self-types-exact-flat.errors.txt | 107 +++ .../reference/self-types-exact-flat.js | 101 +++ .../reference/self-types-exact-flat.symbols | 290 +++++++ .../reference/self-types-exact-flat.types | 193 +++++ .../reference/self-types-exact.errors.txt | 49 ++ tests/baselines/reference/self-types-exact.js | 43 ++ .../reference/self-types-exact.symbols | 100 +++ .../reference/self-types-exact.types | 65 ++ .../self-types-json-simple.errors.txt | 55 ++ .../reference/self-types-json-simple.js | 46 ++ .../reference/self-types-json-simple.symbols | 75 ++ .../reference/self-types-json-simple.types | 79 ++ .../reference/self-types-json.errors.txt | 96 +++ tests/baselines/reference/self-types-json.js | 94 +++ .../reference/self-types-json.symbols | 248 ++++++ .../baselines/reference/self-types-json.types | 177 +++++ .../reference/self-types-keyof.errors.txt | 35 + tests/baselines/reference/self-types-keyof.js | 30 + .../reference/self-types-keyof.symbols | 60 ++ .../reference/self-types-keyof.types | 45 ++ .../reference/self-types-mapped.errors.txt | 201 +++++ .../baselines/reference/self-types-mapped.js | 196 +++++ .../reference/self-types-mapped.symbols | 472 ++++++++++++ .../reference/self-types-mapped.types | 254 +++++++ .../self-types-non-zero-number.errors.txt | 23 + .../reference/self-types-non-zero-number.js | 23 + .../self-types-non-zero-number.symbols | 32 + .../self-types-non-zero-number.types | 42 ++ .../self-types-probability.errors.txt | 56 ++ .../reference/self-types-probability.js | 51 ++ .../reference/self-types-probability.symbols | 103 +++ .../reference/self-types-probability.types | 98 +++ .../self-types-state-machine.errors.txt | 30 + .../reference/self-types-state-machine.js | 40 + .../self-types-state-machine.symbols | 50 ++ .../reference/self-types-state-machine.types | 58 ++ .../self-types-string-literal.errors.txt | 29 + .../reference/self-types-string-literal.js | 27 + .../self-types-string-literal.symbols | 50 ++ .../reference/self-types-string-literal.types | 62 ++ .../self-types-tuple-from-union.errors.txt | 72 ++ .../reference/self-types-tuple-from-union.js | 68 ++ .../self-types-tuple-from-union.symbols | 186 +++++ .../self-types-tuple-from-union.types | 111 +++ 52 files changed, 6118 insertions(+) create mode 100644 tests/baselines/reference/self-types-case-insensitive.errors.txt create mode 100644 tests/baselines/reference/self-types-case-insensitive.js create mode 100644 tests/baselines/reference/self-types-case-insensitive.symbols create mode 100644 tests/baselines/reference/self-types-case-insensitive.types create mode 100644 tests/baselines/reference/self-types-color.errors.txt create mode 100644 tests/baselines/reference/self-types-color.js create mode 100644 tests/baselines/reference/self-types-color.symbols create mode 100644 tests/baselines/reference/self-types-color.types create mode 100644 tests/baselines/reference/self-types-exact-flat.errors.txt create mode 100644 tests/baselines/reference/self-types-exact-flat.js create mode 100644 tests/baselines/reference/self-types-exact-flat.symbols create mode 100644 tests/baselines/reference/self-types-exact-flat.types create mode 100644 tests/baselines/reference/self-types-exact.errors.txt create mode 100644 tests/baselines/reference/self-types-exact.js create mode 100644 tests/baselines/reference/self-types-exact.symbols create mode 100644 tests/baselines/reference/self-types-exact.types create mode 100644 tests/baselines/reference/self-types-json-simple.errors.txt create mode 100644 tests/baselines/reference/self-types-json-simple.js create mode 100644 tests/baselines/reference/self-types-json-simple.symbols create mode 100644 tests/baselines/reference/self-types-json-simple.types create mode 100644 tests/baselines/reference/self-types-json.errors.txt create mode 100644 tests/baselines/reference/self-types-json.js create mode 100644 tests/baselines/reference/self-types-json.symbols create mode 100644 tests/baselines/reference/self-types-json.types create mode 100644 tests/baselines/reference/self-types-keyof.errors.txt create mode 100644 tests/baselines/reference/self-types-keyof.js create mode 100644 tests/baselines/reference/self-types-keyof.symbols create mode 100644 tests/baselines/reference/self-types-keyof.types create mode 100644 tests/baselines/reference/self-types-mapped.errors.txt create mode 100644 tests/baselines/reference/self-types-mapped.js create mode 100644 tests/baselines/reference/self-types-mapped.symbols create mode 100644 tests/baselines/reference/self-types-mapped.types create mode 100644 tests/baselines/reference/self-types-non-zero-number.errors.txt create mode 100644 tests/baselines/reference/self-types-non-zero-number.js create mode 100644 tests/baselines/reference/self-types-non-zero-number.symbols create mode 100644 tests/baselines/reference/self-types-non-zero-number.types create mode 100644 tests/baselines/reference/self-types-probability.errors.txt create mode 100644 tests/baselines/reference/self-types-probability.js create mode 100644 tests/baselines/reference/self-types-probability.symbols create mode 100644 tests/baselines/reference/self-types-probability.types create mode 100644 tests/baselines/reference/self-types-state-machine.errors.txt create mode 100644 tests/baselines/reference/self-types-state-machine.js create mode 100644 tests/baselines/reference/self-types-state-machine.symbols create mode 100644 tests/baselines/reference/self-types-state-machine.types create mode 100644 tests/baselines/reference/self-types-string-literal.errors.txt create mode 100644 tests/baselines/reference/self-types-string-literal.js create mode 100644 tests/baselines/reference/self-types-string-literal.symbols create mode 100644 tests/baselines/reference/self-types-string-literal.types create mode 100644 tests/baselines/reference/self-types-tuple-from-union.errors.txt create mode 100644 tests/baselines/reference/self-types-tuple-from-union.js create mode 100644 tests/baselines/reference/self-types-tuple-from-union.symbols create mode 100644 tests/baselines/reference/self-types-tuple-from-union.types 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..f7b63b5c88b21 --- /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"; +exports.__esModule = 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..2ff5f2a80c89d --- /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"; +exports.__esModule = 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..c9aadf34169eb --- /dev/null +++ b/tests/baselines/reference/self-types-color.types @@ -0,0 +1,424 @@ +=== tests/cases/compiler/self-types-color.ts === +type Color = +>Color : self extends string ? ParseColor extends infer R ? R extends { error: infer E extends string; } ? never : R : never : string + + 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..3f58718afab5f --- /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"; +exports.__esModule = 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..bf20c755bb4dc --- /dev/null +++ b/tests/baselines/reference/self-types-exact.errors.txt @@ -0,0 +1,49 @@ +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 = + 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..7568d09ba08b8 --- /dev/null +++ b/tests/baselines/reference/self-types-exact.js @@ -0,0 +1,43 @@ +//// [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 = + 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"; +exports.__esModule = 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..2d01af7f2bac9 --- /dev/null +++ b/tests/baselines/reference/self-types-exact.symbols @@ -0,0 +1,100 @@ +=== 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)) +>A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) + + A extends T +>A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) + + ? T extends unknown +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) + + ? A extends (...a: infer Aa) => infer Ar +>A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) +>a : Symbol(a, Decl(self-types-exact.ts, 14, 21)) +>Aa : Symbol(Aa, Decl(self-types-exact.ts, 14, 32)) +>Ar : Symbol(Ar, Decl(self-types-exact.ts, 14, 45)) + + ? T extends (...a: infer Ea) => infer Er +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) +>a : Symbol(a, Decl(self-types-exact.ts, 15, 25)) +>Ea : Symbol(Ea, Decl(self-types-exact.ts, 15, 36)) +>Er : Symbol(Er, Decl(self-types-exact.ts, 15, 49)) + + ? (...a: Exact) => Exact +>a : Symbol(a, Decl(self-types-exact.ts, 16, 19)) +>Exact : Symbol(Exact, Decl(self-types-exact.ts, 9, 3)) +>Ea : Symbol(Ea, Decl(self-types-exact.ts, 15, 36)) +>Aa : Symbol(Aa, Decl(self-types-exact.ts, 14, 32)) +>Exact : Symbol(Exact, Decl(self-types-exact.ts, 9, 3)) +>Er : Symbol(Er, Decl(self-types-exact.ts, 15, 49)) +>Ar : Symbol(Ar, Decl(self-types-exact.ts, 14, 45)) + + : T : +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) + + A extends object +>A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) + + ? T extends object +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) + + ? { [K in keyof A]: +>K : Symbol(K, Decl(self-types-exact.ts, 20, 21)) +>A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) + + K extends keyof T ? Exact : +>K : Symbol(K, Decl(self-types-exact.ts, 20, 21)) +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) +>Exact : Symbol(Exact, Decl(self-types-exact.ts, 9, 3)) +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) +>K : Symbol(K, Decl(self-types-exact.ts, 20, 21)) +>A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) +>K : Symbol(K, Decl(self-types-exact.ts, 20, 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, 20, 21)) + } + : T : +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) + + T +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) + + : never + : T +>T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) + +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..0382429e8cc30 --- /dev/null +++ b/tests/baselines/reference/self-types-exact.types @@ -0,0 +1,65 @@ +=== 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 + + 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..9a5e8527f4258 --- /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"; +exports.__esModule = 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..178e8305deb8f --- /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 : string | number | boolean | { toJSON: () => string; } | (self extends unknown[] ? Json[] : self extends (...a: never[]) => unknown ? never : { [_ in keyof self]: Json; }) | (self extends (...a: never[]) => unknown ? never : never) + + | 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] : string[] +>"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..47ade9cd2f3e7 --- /dev/null +++ b/tests/baselines/reference/self-types-json.errors.txt @@ -0,0 +1,96 @@ +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,5): 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 + 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() + ~~ +!!! 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..9a86947af0aff --- /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() +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"; +exports.__esModule = 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(); +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..3ea205f55a9c3 --- /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() +>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..928e5c93fa420 --- /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() +>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..d7c4a187161f8 --- /dev/null +++ b/tests/baselines/reference/self-types-keyof.errors.txt @@ -0,0 +1,35 @@ +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(17,5): error TS2322: Type '{ a: number; } extends { [_ in KeyOf<{ a: number; }>]: infer X; } ? X : never' is not assignable to type 'number'. + Type 'unknown' is not assignable to type 'number'. +tests/cases/compiler/self-types-keyof.ts(17,33): error TS2345: Argument of type 'string' is not assignable to parameter of type 'KeyOf<{ a: number; }>'. + + +==== tests/cases/compiler/self-types-keyof.ts (3 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" as "a") + ~~ +!!! error TS2322: Type '{ a: number; } extends { [_ in KeyOf<{ a: number; }>]: infer X; } ? X : never' is not assignable to type 'number'. +!!! error TS2322: Type 'unknown' is not assignable to type 'number'. + ~~~~~~~~~~ +!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'KeyOf<{ a: number; }>'. + // TODO?: this should compile + + 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..d7b1c6e6bde6b --- /dev/null +++ b/tests/baselines/reference/self-types-keyof.js @@ -0,0 +1,30 @@ +//// [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" as "a") +// TODO?: this should compile + +export {} + + +//// [self-types-keyof.js] +"use strict"; +// Implementing index types without index types +exports.__esModule = true; +var t0 = "a"; +var t1 = "b"; +var t3 = get({ a: 10 }, "a"); diff --git a/tests/baselines/reference/self-types-keyof.symbols b/tests/baselines/reference/self-types-keyof.symbols new file mode 100644 index 0000000000000..a9c8c54731390 --- /dev/null +++ b/tests/baselines/reference/self-types-keyof.symbols @@ -0,0 +1,60 @@ +=== 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" as "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)) + +// TODO?: this should compile + +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..468f369518862 --- /dev/null +++ b/tests/baselines/reference/self-types-keyof.types @@ -0,0 +1,45 @@ +=== 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" as "a") +>t3 : number +>get({ a: 10 }, "a" as "a") : { 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 +>"a" as "a" : "a" +>"a" : "a" + +// TODO?: this should compile + +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..32f6df2401e46 --- /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 +exports.__esModule = 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..02fef18af1c72 --- /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 : _Partial + +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 : _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 : FlipValues + + 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..4e69abe8e0dc0 --- /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"; +exports.__esModule = 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..5d248342d0cb5 --- /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 : self extends number ? self extends 0 ? never : self : number + + 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-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..c73ece8dc594e --- /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"; +exports.__esModule = 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..fd3990d105702 --- /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 : self extends number ? IsProbability extends true ? self : never : number + + 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-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..0813afae5450f --- /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 : { [S in keyof self]: { [E in keyof self[S]]: keyof self; }; } + + { [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..e60009f59d3d3 --- /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 : self extends string ? string extends self ? never : self : string + + 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..317e65b9d2b0d --- /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"; +exports.__esModule = 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 {} + From a41f15bb0e0877eb2ce25a7974871e47426a5954 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Tue, 3 Jan 2023 20:41:01 +0000 Subject: [PATCH 08/30] fix lint --- src/compiler/checker.ts | 168 ++++++++++++++++++++-------------------- src/compiler/types.ts | 168 ++++++++++++++++++++-------------------- 2 files changed, 168 insertions(+), 168 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bd5e5f8d011af..c307028b63ac0 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -337,8 +337,8 @@ import { hasAccessorModifier, hasAmbientModifier, hasContextSensitiveParameters, - hasDecorators, HasDecorators, + hasDecorators, hasDynamicName, hasEffectiveModifier, hasEffectiveModifiers, @@ -347,8 +347,8 @@ import { hasExtension, HasIllegalDecorators, HasIllegalModifiers, - hasInitializer, HasInitializer, + hasInitializer, hasJSDocNodes, hasJSDocParameterTags, hasJsonModuleEmitEnabled, @@ -783,6 +783,7 @@ import { NamespaceExportDeclaration, NamespaceImport, needsScopeMarker, + NeverWithErrorType, NewExpression, Node, NodeArray, @@ -832,6 +833,7 @@ import { PlusToken, PostfixUnaryExpression, PrefixUnaryExpression, + PrintType, PrivateIdentifier, Program, PromiseOrAwaitableType, @@ -1010,8 +1012,6 @@ import { WideningContext, WithStatement, YieldExpression, - NeverWithErrorType, - PrintType, } from "./_namespaces/ts"; import * as performance from "./_namespaces/ts.performance"; import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers"; @@ -1811,8 +1811,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 neverWithErrorTypes = new Map(); + const printTypes = new Map(); const unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String); const resolvingSymbol = createSymbol(0, InternalSymbolName.Resolving); @@ -6348,39 +6348,39 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (type.flags & TypeFlags.TemplateLiteral) { let texts = [...(type as TemplateLiteralType).texts]; let types = [...(type as TemplateLiteralType).types]; - console.log("template before") - console.log(JSON.stringify(texts)) - console.log(JSON.stringify(types.map(t => typeToString(t)))) - + console.log("template before"); + console.log(JSON.stringify(texts)); + console.log(JSON.stringify(types.map(t => typeToString(t)))); + const textOrTypes = flatMap(texts, (text, i) => [ { kind: "text" as const, value: text }, ...(types[i] ? [{ kind: "type" as const, value: types[i] }] : []) - ]) + ]); - texts = [] - types = [] + texts = []; + types = []; for (let i = 0; i < textOrTypes.length;) { - let element = textOrTypes[i] + const element = textOrTypes[i]; if (element.kind === "type" && element.value.flags & TypeFlags.Print) { - element.value = getStringLiteralTypeFromPrintType(element.value as PrintType) + 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 + 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) + if (element.kind === "text") texts.push(element.value); + if (element.kind === "type") types.push(element.value); i++; } - console.log("template after") - console.log(JSON.stringify(texts)) - console.log(JSON.stringify(types.map(t => typeToString(t)))) + console.log("template after"); + console.log(JSON.stringify(texts)); + console.log(JSON.stringify(types.map(t => typeToString(t)))); if (types.length === 0) { - return typeToTypeNodeHelper(getStringLiteralType(texts.join("")), context) + return typeToTypeNodeHelper(getStringLiteralType(texts.join("")), context); } const templateHead = factory.createTemplateHead(texts[0]); @@ -6396,7 +6396,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return symbolToTypeNode((type as StringMappingType).symbol, context, SymbolFlags.Type, [typeNode]); } if (type.flags & TypeFlags.Print) { - return typeToTypeNodeHelper(getStringLiteralTypeFromPrintType(type as PrintType), context) + return typeToTypeNodeHelper(getStringLiteralTypeFromPrintType(type as PrintType), context); } if (type.flags & TypeFlags.IndexedAccess) { const objectTypeNode = typeToTypeNodeHelper((type as IndexedAccessType).objectType, context); @@ -11774,10 +11774,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let type = typeNode ? getTypeFromTypeNode(typeNode) : errorType; const containsSelfType = !!forEachChildRecursively(declaration, node => { - if (node.kind === SyntaxKind.SelfKeyword) return true + if (node.kind === SyntaxKind.SelfKeyword) return true; }); - if (containsSelfType) { - type.flags |= TypeFlags.ContainsSelf + if (containsSelfType) { + type.flags |= TypeFlags.ContainsSelf; } if (popTypeResolution()) { @@ -13500,7 +13500,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return constraint && constraint !== (t as StringMappingType).type ? getStringMappingType((t as StringMappingType).symbol, constraint) : stringType; } if (t.flags & TypeFlags.Print) { - return stringType + return stringType; } if (t.flags & TypeFlags.IndexedAccess) { if (isMappedTypeGenericIndexedAccess(t)) { @@ -14921,7 +14921,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return createNeverWithErrorType(typeArguments[0]); case IntrinsicTypeKind.Print: - return createPrintType(typeArguments[0], typeArguments[1]) + return createPrintType(typeArguments[0], typeArguments[1]); } } @@ -14930,11 +14930,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const id = getTypeListId(typeArguments) + getAliasId(aliasSymbol, aliasTypeArguments); let instantiation = links.instantiations!.get(id); if (!instantiation) { - const filledTypeArguments = fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration)) + const filledTypeArguments = fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration)); const mapper = typeParameters ? createTypeMapper(typeParameters, filledTypeArguments) : createTypeMapper([], []); - instantiation = instantiateTypeWithAlias(type, mapper, aliasSymbol, aliasTypeArguments) + instantiation = instantiateTypeWithAlias(type, mapper, aliasSymbol, aliasTypeArguments); if (type.flags & TypeFlags.ContainsSelf) { - instantiation.flags |= TypeFlags.ContainsSelf + instantiation.flags |= TypeFlags.ContainsSelf; } links.instantiations!.set(id, instantiation); } @@ -14960,9 +14960,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return errorType; } const type = getDeclaredTypeOfSymbol(symbol); - const links = getSymbolLinks(symbol) + const links = getSymbolLinks(symbol); const typeParameters = links.typeParameters; - const selfType = links.selfType + const selfType = links.selfType; if (typeParameters || selfType) { if (typeParameters) { const numTypeArguments = length(node.typeArguments); @@ -16848,43 +16848,43 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function createNeverWithErrorType(errorType: Type) { - const id = `${getTypeId(errorType)}` - if (neverWithErrorTypes.has(id)) return neverWithErrorTypes.get(id)! + 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 + const type = createType(TypeFlags.Never | TypeFlags.NeverWithError) as NeverWithErrorType; + type.intrinsicName = "NeverWithError"; + type.errorType = errorType; - neverWithErrorTypes.set(id, type) - return type + 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 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 + printType.type = type; + printType.flagType = flagType; - printTypes.set(id, printType) - return printType + printTypes.set(id, printType); + return printType; } function getStringLiteralTypeFromPrintType(printType: PrintType) { if (printType.resolvedStringLiteralType) { - return printType.resolvedStringLiteralType + return printType.resolvedStringLiteralType; } const type = getStringLiteralType(typeToString( - printType.type, undefined, + printType.type, /* enclosingDeclaration */ undefined, isTypeSubtypeOf(getStringLiteralType("InTypeAlias"), printType.flagType) ? TypeFormatFlags.InTypeAlias : TypeFormatFlags.None - )) - - printType.resolvedStringLiteralType = type - return type + )); + + printType.resolvedStringLiteralType = type; + return type; } /** @@ -18058,24 +18058,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function getTypeFromSelfTypeNode(node: Node): Type { - const links = getNodeLinks(node) + 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)!) + 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 + links.resolvedType = typeAliasLinks.selfType; + return links.resolvedType; } - const localSelfType = createTypeParameter() as TypeParameter & IntrinsicType - localSelfType.intrinsicName = "self" - localSelfType.flags |= TypeFlags.Self - typeAliasLinks.selfType = localSelfType + const localSelfType = createTypeParameter() as TypeParameter & IntrinsicType; + localSelfType.intrinsicName = "self"; + localSelfType.flags |= TypeFlags.Self; + typeAliasLinks.selfType = localSelfType; - links.resolvedType = localSelfType - return links.resolvedType + links.resolvedType = localSelfType; + return links.resolvedType; } function getTypeFromRestTypeNode(node: RestTypeNode | NamedTupleMember) { @@ -18743,7 +18743,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return createPrintType( instantiateType((type as PrintType).type, mapper), instantiateType((type as PrintType).flagType, mapper) - ) + ); } if (flags & TypeFlags.IndexedAccess) { const newAliasSymbol = aliasSymbol || type.aliasSymbol; @@ -18768,7 +18768,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return newBaseType.flags & TypeFlags.TypeVariable ? getSubstitutionType(newBaseType, newConstraint) : getIntersectionType([newConstraint, newBaseType]); } if (flags & TypeFlags.NeverWithError) { - return createNeverWithErrorType(instantiateType((type as NeverWithErrorType).errorType, mapper)) + return createNeverWithErrorType(instantiateType((type as NeverWithErrorType).errorType, mapper)); } return type; } @@ -19733,11 +19733,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter): boolean { if (!(target.flags & TypeFlags.ContainsSelf && source.flags & TypeFlags.ContainsSelf)) { if (target.flags & TypeFlags.ContainsSelf) { - let targetSelfType = getSymbolLinks(target.aliasSymbol!).selfType! + const targetSelfType = getSymbolLinks(target.aliasSymbol!).selfType!; target = instantiateType(target, makeUnaryTypeMapper(targetSelfType, source)); } if (source.flags & TypeFlags.ContainsSelf) { - let sourceSelfType = getSymbolLinks(source.aliasSymbol!).selfType! + const sourceSelfType = getSymbolLinks(source.aliasSymbol!).selfType!; source = instantiateType(source, makeUnaryTypeMapper(sourceSelfType, target)); } } @@ -19786,11 +19786,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function isTypeRelatedTo(source: Type, target: Type, relation: Map) { if (!(target.flags & TypeFlags.ContainsSelf && source.flags & TypeFlags.ContainsSelf)) { if (target.flags & TypeFlags.ContainsSelf) { - let targetSelfType = getSymbolLinks(target.aliasSymbol!).selfType! + const targetSelfType = getSymbolLinks(target.aliasSymbol!).selfType!; target = instantiateType(target, makeUnaryTypeMapper(targetSelfType, source)); } if (source.flags & TypeFlags.ContainsSelf) { - let sourceSelfType = getSymbolLinks(source.aliasSymbol!).selfType! + const sourceSelfType = getSymbolLinks(source.aliasSymbol!).selfType!; source = instantiateType(source, makeUnaryTypeMapper(sourceSelfType, target)); } } @@ -20099,15 +20099,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const [sourceType, targetType] = getTypeNamesForErrorDisplay(source, target); let generalizedSource = source; let generalizedSourceType = sourceType; - + if (target.flags & TypeFlags.NeverWithError) { - const errorType = (target as NeverWithErrorType).errorType - const errorsType = (isTypeSubtypeOf(errorType, stringType) ? createTupleType([errorType]) : errorType) - if (!isTupleType(errorsType)) return reportNonCustom() - - const errorTypes: Type[] = Array.from({ length: errorsType.target.fixedLength }, (_, i) => getTupleElementType(errorsType, i)!) - if (!every(errorTypes, t => !!(t.flags & TypeFlags.StringLike))) return reportNonCustom() - + const errorType = (target as NeverWithErrorType).errorType; + const errorsType = (isTypeSubtypeOf(errorType, stringType) ? createTupleType([errorType]) : errorType); + if (!isTupleType(errorsType)) return reportNonCustom(); + + 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, typeToString(errorTypes.pop()!) @@ -20116,11 +20116,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { .replace(/\\'/g, "'") .replace(/\\\\/g, "\\") .replace(/\\n/g, "\n") - ) + ); } - return + return; } - return reportNonCustom() + return reportNonCustom(); function reportNonCustom() { if (isLiteralType(source) && !typeCouldHaveTopLevelSingletonTypes(target)) { @@ -20241,11 +20241,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function isRelatedTo(originalSource: Type, originalTarget: Type, recursionFlags: RecursionFlags = RecursionFlags.Both, reportErrors = false, headMessage?: DiagnosticMessage, intersectionState = IntersectionState.None): Ternary { if (!(originalTarget.flags & TypeFlags.ContainsSelf && originalSource.flags & TypeFlags.ContainsSelf)) { if (originalTarget.flags & TypeFlags.ContainsSelf) { - let targetSelfType = getSymbolLinks(originalTarget.aliasSymbol!).selfType! + const targetSelfType = getSymbolLinks(originalTarget.aliasSymbol!).selfType!; originalTarget = instantiateType(originalTarget, makeUnaryTypeMapper(targetSelfType, originalSource)); } if (originalSource.flags & TypeFlags.ContainsSelf) { - let sourceSelfType = getSymbolLinks(originalSource.aliasSymbol!).selfType! + const sourceSelfType = getSymbolLinks(originalSource.aliasSymbol!).selfType!; originalSource = instantiateType(originalSource, makeUnaryTypeMapper(sourceSelfType, originalTarget)); } } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index bcb91fcf8e851..27c30693a413e 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5686,102 +5686,102 @@ export interface NodeLinks { serializedTypes?: Map; // Collection of types serialized at this location } -export type TypeFlags = (typeof TypeFlags)[keyof typeof TypeFlags] +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 - ContainsSelf = 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.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 + 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; + ContainsSelf = 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.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 = this.Any | this.Unknown | this.StructuredOrInstantiable | this.StringLike | this.NumberLike | this.BigIntLike | this.BooleanLike | this.ESSymbol | this.UniqueESSymbol | this.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 = this.Any | this.Unknown | this.Primitive | this.Never | this.Object | this.Union | this.Intersection | this.NonPrimitive | this.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 = this.TypeParameter + IncludesMissingType = this.TypeParameter; /** @internal */ - IncludesNonWideningType = this.Index + IncludesNonWideningType = this.Index; /** @internal */ - IncludesWildcard = this.IndexedAccess + IncludesWildcard = this.IndexedAccess; /** @internal */ - IncludesEmptyObject = this.Conditional + IncludesEmptyObject = this.Conditional; /** @internal */ - IncludesInstantiable = this.Substitution + IncludesInstantiable = this.Substitution; /** @internal */ - NotPrimitiveUnion = this.Any | this.Unknown | this.Enum | this.Void | this.Never | this.Object | this.Intersection | this.IncludesInstantiable -} + NotPrimitiveUnion = this.Any | this.Unknown | this.Enum | this.Void | this.Never | this.Object | this.Intersection | this.IncludesInstantiable; +}(); export type DestructuringPattern = BindingPattern | ObjectLiteralExpression | ArrayLiteralExpression; From ea6d257716c92db200c02a166cf4645d31e9ef95 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Tue, 3 Jan 2023 20:41:36 +0000 Subject: [PATCH 09/30] remove debug logging --- src/compiler/checker.ts | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c307028b63ac0..8f0109e6f4e91 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6348,9 +6348,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (type.flags & TypeFlags.TemplateLiteral) { let texts = [...(type as TemplateLiteralType).texts]; let types = [...(type as TemplateLiteralType).types]; - console.log("template before"); - console.log(JSON.stringify(texts)); - console.log(JSON.stringify(types.map(t => typeToString(t)))); const textOrTypes = flatMap(texts, (text, i) => [ { kind: "text" as const, value: text }, @@ -6375,9 +6372,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (element.kind === "type") types.push(element.value); i++; } - console.log("template after"); - console.log(JSON.stringify(texts)); - console.log(JSON.stringify(types.map(t => typeToString(t)))); if (types.length === 0) { return typeToTypeNodeHelper(getStringLiteralType(texts.join("")), context); From 389833b26d2f5c84ff786fe67e4d718d816358a8 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Tue, 3 Jan 2023 21:02:33 +0000 Subject: [PATCH 10/30] fix code to accomodate #51682 --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index de1352605ff22..8dfff08d1e763 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -11363,7 +11363,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { getDeclaredTypeOfClassOrInterface(getSymbolOfDeclaration(node as ClassLikeDeclaration | InterfaceDeclaration)).thisType; const selfType = - node.kind === SyntaxKind.TypeAliasDeclaration ? getSymbolLinks(node.symbol).selfType : undefined; + node.kind === SyntaxKind.TypeAliasDeclaration ? getSymbolLinks(getSymbolOfDeclaration(node as TypeAliasDeclaration)).selfType : undefined; const implicitTypeParameters = [ ...(thisType ? [thisType] : []), From 0e3839565810644a486e42cd754f6ba3177cdc36 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Tue, 3 Jan 2023 21:55:52 +0000 Subject: [PATCH 11/30] allow intrinsic keyword in new intrinsic types --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 8dfff08d1e763..3dd02c52bd300 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -42293,7 +42293,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); } } From c10528bb64ebe8f39d7296eda5676fc732634588 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Tue, 3 Jan 2023 23:34:18 +0000 Subject: [PATCH 12/30] add self as a global keyword in fourslash --- src/harness/fourslashInterfaceImpl.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 65fa8d90a6871..4f179f5406cf8 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1626,6 +1626,7 @@ export namespace Completion { "typeof", "unique", "unknown", + "self", "var", "void", "while", From e3cff6b3620f71303f3b567149d112ce9de486aa Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Tue, 3 Jan 2023 23:58:51 +0000 Subject: [PATCH 13/30] add "self" to more places in fourslash --- src/harness/fourslashInterfaceImpl.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 4f179f5406cf8..8d56b1e6d1265 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1091,6 +1091,7 @@ export namespace Completion { "undefined", "unique", "unknown", + "self", "void", ].map(keywordEntry); @@ -1269,6 +1270,7 @@ export namespace Completion { case "unique": case "override": case "unknown": + case "self": case "global": case "bigint": return false; @@ -1411,6 +1413,7 @@ export namespace Completion { "typeof", "unique", "unknown", + "self", "var", "void", "while", From 9c076aa86b1c196335c680ccc5c43e1183f77e2d Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Wed, 4 Jan 2023 00:46:29 +0000 Subject: [PATCH 14/30] remove accidently added `Map` global in fourslash --- src/harness/fourslashInterfaceImpl.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 8d56b1e6d1265..a851ad2165729 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1221,8 +1221,7 @@ export namespace Completion { interfaceEntry("Float32ArrayConstructor"), varEntry("Float64Array"), interfaceEntry("Float64ArrayConstructor"), - moduleEntry("Intl"), - varEntry("Map") + moduleEntry("Intl") ]; export const globalThisEntry: ExpectedCompletionEntry = { From afdc60e62b8427bf49383bcd5b0a463a5f4cff10 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Wed, 4 Jan 2023 00:47:07 +0000 Subject: [PATCH 15/30] remove a possibly false positive debug assertion --- src/compiler/checker.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 3dd02c52bd300..f73af54ed34bd 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20139,7 +20139,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function reportNonCustom() { if (isLiteralType(source) && !typeCouldHaveTopLevelSingletonTypes(target)) { generalizedSource = getBaseTypeOfLiteralType(source); - Debug.assert(!isTypeAssignableTo(generalizedSource, target), "generalized source shouldn't be assignable"); + // 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); } From a1fb8210d4dd74578702c3db9acafe07daab87b8 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Wed, 4 Jan 2023 01:14:09 +0000 Subject: [PATCH 16/30] remove a todo as it got fixed after resolving conflicts --- tests/cases/compiler/self-types-not.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/compiler/self-types-not.ts b/tests/cases/compiler/self-types-not.ts index 5f241c38f4db9..39cc8f5776601 100644 --- a/tests/cases/compiler/self-types-not.ts +++ b/tests/cases/compiler/self-types-not.ts @@ -5,7 +5,7 @@ type Not = const divide = (a: number, b: number & Not<0>) => a / b -divide(1, 0) // TODO: shouldn't compile +divide(1, 0) divide(1, 1) divide(1, "x") From 2ee5f956df5d1438722d46f5c38228b37b46a429 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Wed, 4 Jan 2023 01:17:02 +0000 Subject: [PATCH 17/30] accept new baseline for new tests after resolving conflict --- .../reference/self-types-case-insensitive.js | 2 +- tests/baselines/reference/self-types-color.js | 2 +- .../reference/self-types-exact-flat.js | 2 +- tests/baselines/reference/self-types-exact.js | 2 +- .../reference/self-types-json-simple.js | 2 +- tests/baselines/reference/self-types-json.js | 2 +- tests/baselines/reference/self-types-keyof.js | 2 +- .../baselines/reference/self-types-mapped.js | 2 +- .../reference/self-types-non-zero-number.js | 2 +- .../reference/self-types-not.errors.txt | 25 +++++++++++++ tests/baselines/reference/self-types-not.js | 21 +++++++++++ .../reference/self-types-not.symbols | 34 ++++++++++++++++++ .../baselines/reference/self-types-not.types | 36 +++++++++++++++++++ .../reference/self-types-probability.js | 2 +- .../reference/self-types-tuple-from-union.js | 2 +- 15 files changed, 127 insertions(+), 11 deletions(-) create mode 100644 tests/baselines/reference/self-types-not.errors.txt create mode 100644 tests/baselines/reference/self-types-not.js create mode 100644 tests/baselines/reference/self-types-not.symbols create mode 100644 tests/baselines/reference/self-types-not.types diff --git a/tests/baselines/reference/self-types-case-insensitive.js b/tests/baselines/reference/self-types-case-insensitive.js index f7b63b5c88b21..b4d0c2a3955a6 100644 --- a/tests/baselines/reference/self-types-case-insensitive.js +++ b/tests/baselines/reference/self-types-case-insensitive.js @@ -37,7 +37,7 @@ export {} //// [self-types-case-insensitive.js] "use strict"; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); setHeader("Set-Cookie", "test"); setHeader("Accept", "test2"); setHeader("sEt-cOoKiE", "stop writing headers like this but ok"); diff --git a/tests/baselines/reference/self-types-color.js b/tests/baselines/reference/self-types-color.js index 2ff5f2a80c89d..ef6ebf949a51a 100644 --- a/tests/baselines/reference/self-types-color.js +++ b/tests/baselines/reference/self-types-color.js @@ -186,7 +186,7 @@ export namespace A { //// [self-types-color.js] "use strict"; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); var t0 = 123; var t1 = "hello"; var t2 = "#fff"; diff --git a/tests/baselines/reference/self-types-exact-flat.js b/tests/baselines/reference/self-types-exact-flat.js index 3f58718afab5f..41088c664e61c 100644 --- a/tests/baselines/reference/self-types-exact-flat.js +++ b/tests/baselines/reference/self-types-exact-flat.js @@ -84,7 +84,7 @@ export {} //// [self-types-exact-flat.js] "use strict"; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); f(function () { return ({ a: { b: "b", diff --git a/tests/baselines/reference/self-types-exact.js b/tests/baselines/reference/self-types-exact.js index 7568d09ba08b8..2232aba4acb4f 100644 --- a/tests/baselines/reference/self-types-exact.js +++ b/tests/baselines/reference/self-types-exact.js @@ -32,7 +32,7 @@ export {} //// [self-types-exact.js] "use strict"; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); f(function () { return ({ a: { b: "b", diff --git a/tests/baselines/reference/self-types-json-simple.js b/tests/baselines/reference/self-types-json-simple.js index 9a5e8527f4258..8dcaac5f45844 100644 --- a/tests/baselines/reference/self-types-json-simple.js +++ b/tests/baselines/reference/self-types-json-simple.js @@ -31,7 +31,7 @@ export {} //// [self-types-json-simple.js] "use strict"; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); var someNode = {}; var t1 = someNode; // TODO: this should probably compile var t3 = function () { return "hello"; }; diff --git a/tests/baselines/reference/self-types-json.js b/tests/baselines/reference/self-types-json.js index 9a86947af0aff..1dedc23841449 100644 --- a/tests/baselines/reference/self-types-json.js +++ b/tests/baselines/reference/self-types-json.js @@ -77,7 +77,7 @@ export {} //// [self-types-json.js] "use strict"; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); var someNode = {}; var t1 = someNode; var t2 = someNode; diff --git a/tests/baselines/reference/self-types-keyof.js b/tests/baselines/reference/self-types-keyof.js index d7b1c6e6bde6b..38eb5b2afdef0 100644 --- a/tests/baselines/reference/self-types-keyof.js +++ b/tests/baselines/reference/self-types-keyof.js @@ -24,7 +24,7 @@ export {} //// [self-types-keyof.js] "use strict"; // Implementing index types without index types -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); var t0 = "a"; var t1 = "b"; var t3 = get({ a: 10 }, "a"); diff --git a/tests/baselines/reference/self-types-mapped.js b/tests/baselines/reference/self-types-mapped.js index 32f6df2401e46..a19680e13338f 100644 --- a/tests/baselines/reference/self-types-mapped.js +++ b/tests/baselines/reference/self-types-mapped.js @@ -153,7 +153,7 @@ export {} //// [self-types-mapped.js] "use strict"; // Implementing mapped types without mapped types -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); // same as writing // type _Partial = { [K in keyof T]: T[K] | undefined } var t00 = { diff --git a/tests/baselines/reference/self-types-non-zero-number.js b/tests/baselines/reference/self-types-non-zero-number.js index 4e69abe8e0dc0..a6c65890532e6 100644 --- a/tests/baselines/reference/self-types-non-zero-number.js +++ b/tests/baselines/reference/self-types-non-zero-number.js @@ -16,7 +16,7 @@ export {} //// [self-types-non-zero-number.js] "use strict"; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); var divide = function (a, b) { return (a / b); }; divide(1, 0); divide(1, 1); 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.js b/tests/baselines/reference/self-types-probability.js index c73ece8dc594e..2ca26cd9bf6b0 100644 --- a/tests/baselines/reference/self-types-probability.js +++ b/tests/baselines/reference/self-types-probability.js @@ -38,7 +38,7 @@ export {} //// [self-types-probability.js] "use strict"; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); var t0 = 0.5; var t1 = 0; var t2 = 1; diff --git a/tests/baselines/reference/self-types-tuple-from-union.js b/tests/baselines/reference/self-types-tuple-from-union.js index 317e65b9d2b0d..19eedd0d3062c 100644 --- a/tests/baselines/reference/self-types-tuple-from-union.js +++ b/tests/baselines/reference/self-types-tuple-from-union.js @@ -61,7 +61,7 @@ export {} //// [self-types-tuple-from-union.js] "use strict"; -exports.__esModule = true; +Object.defineProperty(exports, "__esModule", { value: true }); var t0 = ["a", "b", "c"]; var t1 = ["c", "a", "b"]; var t2 = ["a", "x", "c"]; From a805ae9fb568c58015ee232a4a242a7300f4cd51 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Fri, 6 Jan 2023 22:58:28 +0000 Subject: [PATCH 18/30] create a new type construct "Selfed" instead of using the ContainsSelf flag --- src/compiler/checker.ts | 127 ++++++++++++----------- src/compiler/types.ts | 10 +- tests/cases/compiler/self-types-exact.ts | 12 ++- tests/cases/compiler/self-types-json.ts | 2 +- tests/cases/compiler/self-types-keyof.ts | 4 +- tests/cases/compiler/self-types-ryan.ts | 50 +++++++++ 6 files changed, 139 insertions(+), 66 deletions(-) create mode 100644 tests/cases/compiler/self-types-ryan.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index f73af54ed34bd..52c939bd08004 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1033,6 +1033,7 @@ import { WideningContext, WithStatement, YieldExpression, + SelfedType, } from "./_namespaces/ts"; import * as performance from "./_namespaces/ts.performance"; import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers"; @@ -6443,6 +6444,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."); @@ -11780,12 +11784,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.kind === SyntaxKind.SelfKeyword) return true; }); if (containsSelfType) { - type.flags |= TypeFlags.ContainsSelf; + type = createSelfedType(type, links.selfType!) } if (popTypeResolution()) { const typeParameters = getLocalTypeParametersOfClassOrInterfaceOrTypeAlias(symbol); - if (typeParameters || containsSelfType) { + if (typeParameters) { // Initialize the instantiation cache for generic type aliases. The declared type corresponds to // an instantiation of the type alias with the type parameters supplied as type arguments. links.typeParameters = typeParameters; @@ -13528,6 +13532,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; } } @@ -14943,16 +14950,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } const links = getSymbolLinks(symbol); - const typeParameters = links.typeParameters; + const typeParameters = links.typeParameters!; const id = getTypeListId(typeArguments) + getAliasId(aliasSymbol, aliasTypeArguments); let instantiation = links.instantiations!.get(id); if (!instantiation) { const filledTypeArguments = fillMissingTypeArguments(typeArguments, typeParameters, getMinTypeArgumentCount(typeParameters), isInJSFile(symbol.valueDeclaration)); - const mapper = typeParameters ? createTypeMapper(typeParameters, filledTypeArguments) : createTypeMapper([], []); + const mapper = createTypeMapper(typeParameters, filledTypeArguments); instantiation = instantiateTypeWithAlias(type, mapper, aliasSymbol, aliasTypeArguments); - if (type.flags & TypeFlags.ContainsSelf) { - instantiation.flags |= TypeFlags.ContainsSelf; - } links.instantiations!.set(id, instantiation); } return instantiation; @@ -14977,23 +14981,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return errorType; } const type = getDeclaredTypeOfSymbol(symbol); - const links = getSymbolLinks(symbol); - const typeParameters = links.typeParameters; - const selfType = links.selfType; - if (typeParameters || selfType) { - if (typeParameters) { - const numTypeArguments = length(node.typeArguments); - const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); - if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { - error(node, - minTypeArgumentCount === typeParameters.length ? - Diagnostics.Generic_type_0_requires_1_type_argument_s : - Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, - symbolToString(symbol), - minTypeArgumentCount, - typeParameters.length); - return errorType; - } + const typeParameters = getSymbolLinks(symbol).typeParameters; + if (typeParameters) { + const numTypeArguments = length(node.typeArguments); + const minTypeArgumentCount = getMinTypeArgumentCount(typeParameters); + if (numTypeArguments < minTypeArgumentCount || numTypeArguments > typeParameters.length) { + error(node, + minTypeArgumentCount === typeParameters.length ? + Diagnostics.Generic_type_0_requires_1_type_argument_s : + Diagnostics.Generic_type_0_requires_between_1_and_2_type_arguments, + symbolToString(symbol), + minTypeArgumentCount, + typeParameters.length); + return errorType; } // We refrain from associating a local type alias with an instantiation of a top-level type alias // because the local alias may end up being referenced in an inferred return type where it is not @@ -16863,6 +16863,21 @@ 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)!; @@ -18092,9 +18107,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return links.resolvedType; } - const localSelfType = createTypeParameter() as TypeParameter & IntrinsicType; - localSelfType.intrinsicName = "self"; - localSelfType.flags |= TypeFlags.Self; + const localSelfType = createSelfType(); typeAliasLinks.selfType = localSelfType; links.resolvedType = localSelfType; @@ -18790,12 +18803,34 @@ 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 instantiateSelfTypeIfRequired(source: Type, target: Type) { + if (!(source.flags & TypeFlags.Selfed)) return source; + if (target.flags & TypeFlags.Selfed) { + if (getTypeId(target) === getTypeId(source)) return source; + return (source as SelfedType).type; + } + + const sourceSelfed = source as SelfedType; + if (sourceSelfed.instantiations.has(getTypeId(target).toString())) { + return sourceSelfed.instantiations.get(getTypeId(target).toString())!; + } + const instantiated = instantiateType(sourceSelfed.type, makeUnaryTypeMapper(sourceSelfed.selfType, target)); + sourceSelfed.instantiations.set(getTypeId(target).toString(), instantiated); + return instantiated; + } + function instantiateReverseMappedType(type: ReverseMappedType, mapper: TypeMapper) { const innerMappedType = instantiateType(type.mappedType, mapper); if (!(getObjectFlags(innerMappedType) & ObjectFlags.Mapped)) { @@ -19745,16 +19780,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter): boolean { - if (!(target.flags & TypeFlags.ContainsSelf && source.flags & TypeFlags.ContainsSelf)) { - if (target.flags & TypeFlags.ContainsSelf) { - const targetSelfType = getSymbolLinks(target.aliasSymbol!).selfType!; - target = instantiateType(target, makeUnaryTypeMapper(targetSelfType, source)); - } - if (source.flags & TypeFlags.ContainsSelf) { - const sourceSelfType = getSymbolLinks(source.aliasSymbol!).selfType!; - source = instantiateType(source, makeUnaryTypeMapper(sourceSelfType, target)); - } - } + source = instantiateSelfTypeIfRequired(source, target) + target = instantiateSelfTypeIfRequired(target, source) const s = source.flags; const t = target.flags; if (t & TypeFlags.AnyOrUnknown || s & TypeFlags.Never || source === wildcardType) return true; @@ -19798,16 +19825,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isTypeRelatedTo(source: Type, target: Type, relation: Map) { - if (!(target.flags & TypeFlags.ContainsSelf && source.flags & TypeFlags.ContainsSelf)) { - if (target.flags & TypeFlags.ContainsSelf) { - const targetSelfType = getSymbolLinks(target.aliasSymbol!).selfType!; - target = instantiateType(target, makeUnaryTypeMapper(targetSelfType, source)); - } - if (source.flags & TypeFlags.ContainsSelf) { - const sourceSelfType = getSymbolLinks(source.aliasSymbol!).selfType!; - source = instantiateType(source, makeUnaryTypeMapper(sourceSelfType, target)); - } - } + source = instantiateSelfTypeIfRequired(source, target) + target = instantiateSelfTypeIfRequired(target, source) if (isFreshLiteralType(source)) { source = (source as FreshableType).regularType; } @@ -20254,16 +20273,8 @@ 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 { - if (!(originalTarget.flags & TypeFlags.ContainsSelf && originalSource.flags & TypeFlags.ContainsSelf)) { - if (originalTarget.flags & TypeFlags.ContainsSelf) { - const targetSelfType = getSymbolLinks(originalTarget.aliasSymbol!).selfType!; - originalTarget = instantiateType(originalTarget, makeUnaryTypeMapper(targetSelfType, originalSource)); - } - if (originalSource.flags & TypeFlags.ContainsSelf) { - const sourceSelfType = getSymbolLinks(originalSource.aliasSymbol!).selfType!; - originalSource = instantiateType(originalSource, makeUnaryTypeMapper(sourceSelfType, originalTarget)); - } - } + originalSource = instantiateSelfTypeIfRequired(originalSource, originalTarget) + originalTarget = instantiateSelfTypeIfRequired(originalTarget, originalSource) // 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) { @@ -23576,7 +23587,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { 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.ContainsSelf || + 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); diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 727427c7a18e0..d639ac06fff36 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6030,7 +6030,7 @@ export const TypeFlags = new class TypeFlags { TemplateLiteral = 1n << 27n; // Template literal type StringMapping = 1n << 28n; // Uppercase/Lowercase type Self = 1n << 29n; - ContainsSelf = 1n << 30n; + Selfed = 1n << 30n; NeverWithError = 1n << 31n; Print = 1n << 32n; @@ -6064,7 +6064,7 @@ export const TypeFlags = new class TypeFlags { 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.NeverWithError; + 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; @@ -6612,6 +6612,12 @@ 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 +} + export interface NeverWithErrorType extends InstantiableType, IntrinsicType { errorType: Type } diff --git a/tests/cases/compiler/self-types-exact.ts b/tests/cases/compiler/self-types-exact.ts index 5b4050fa6e7d2..15a3c5e7ea881 100644 --- a/tests/cases/compiler/self-types-exact.ts +++ b/tests/cases/compiler/self-types-exact.ts @@ -9,17 +9,23 @@ f(() => ({ y: 1 })) -type Exact = +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 + ? (...a: _Exact) => _Exact : T : A extends object ? T extends object ? { [K in keyof A]: - K extends keyof T ? Exact : + K extends keyof T ? _Exact : Never<`Excess property '${K & string}' not allowed as the target is an exact type`> } : T : diff --git a/tests/cases/compiler/self-types-json.ts b/tests/cases/compiler/self-types-json.ts index 253c3a40390a4..44479276d4919 100644 --- a/tests/cases/compiler/self-types-json.ts +++ b/tests/cases/compiler/self-types-json.ts @@ -13,7 +13,7 @@ let t4: Json = { let t5: Json = { toJSON: () => "hello" } -let t6: Json = new Map() +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] diff --git a/tests/cases/compiler/self-types-keyof.ts b/tests/cases/compiler/self-types-keyof.ts index d0b784f714e95..f81875e4cd332 100644 --- a/tests/cases/compiler/self-types-keyof.ts +++ b/tests/cases/compiler/self-types-keyof.ts @@ -14,7 +14,7 @@ declare const get: >(t: T, k: K) => T extends { [_ in K]: infer X } ? X : never -let t3: number = get({ a: 10 }, "a" as "a") -// TODO?: this should compile +let t3: number = get({ a: 10 }, "a") +let t4 = get({ a: 10 }, "b") export {} 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 From 3e9e52ecf3f63c0d6d905e6ea7f6aefe1e4199d1 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Fri, 6 Jan 2023 22:59:06 +0000 Subject: [PATCH 19/30] accept baseline --- .../reference/self-types-color.types | 2 +- .../reference/self-types-exact.errors.txt | 12 +- tests/baselines/reference/self-types-exact.js | 12 +- .../reference/self-types-exact.symbols | 91 ++++++---- .../reference/self-types-exact.types | 22 ++- .../reference/self-types-json-simple.types | 4 +- .../reference/self-types-json.errors.txt | 7 +- tests/baselines/reference/self-types-json.js | 4 +- .../reference/self-types-json.symbols | 2 +- .../baselines/reference/self-types-json.types | 2 +- .../reference/self-types-keyof.errors.txt | 17 +- tests/baselines/reference/self-types-keyof.js | 5 +- .../reference/self-types-keyof.symbols | 7 +- .../reference/self-types-keyof.types | 14 +- .../reference/self-types-mapped.types | 6 +- .../self-types-non-zero-number.types | 2 +- .../reference/self-types-probability.types | 2 +- .../reference/self-types-ryan.errors.txt | 90 +++++++++ tests/baselines/reference/self-types-ryan.js | 72 ++++++++ .../reference/self-types-ryan.symbols | 171 ++++++++++++++++++ .../baselines/reference/self-types-ryan.types | 139 ++++++++++++++ .../reference/self-types-state-machine.types | 2 +- .../reference/self-types-string-literal.types | 2 +- 23 files changed, 598 insertions(+), 89 deletions(-) create mode 100644 tests/baselines/reference/self-types-ryan.errors.txt create mode 100644 tests/baselines/reference/self-types-ryan.js create mode 100644 tests/baselines/reference/self-types-ryan.symbols create mode 100644 tests/baselines/reference/self-types-ryan.types diff --git a/tests/baselines/reference/self-types-color.types b/tests/baselines/reference/self-types-color.types index c9aadf34169eb..515ba1b26014a 100644 --- a/tests/baselines/reference/self-types-color.types +++ b/tests/baselines/reference/self-types-color.types @@ -1,6 +1,6 @@ === tests/cases/compiler/self-types-color.ts === type Color = ->Color : self extends string ? ParseColor extends infer R ? R extends { error: infer E extends string; } ? never : R : never : string +>Color : Color self extends string ? ParseColor extends infer R diff --git a/tests/baselines/reference/self-types-exact.errors.txt b/tests/baselines/reference/self-types-exact.errors.txt index bf20c755bb4dc..82005f11d23d5 100644 --- a/tests/baselines/reference/self-types-exact.errors.txt +++ b/tests/baselines/reference/self-types-exact.errors.txt @@ -28,17 +28,23 @@ tests/cases/compiler/self-types-exact.ts(3,3): error TS2345: Argument of type '( !!! 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 = + 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 + ? (...a: _Exact) => _Exact : T : A extends object ? T extends object ? { [K in keyof A]: - K extends keyof T ? Exact : + K extends keyof T ? _Exact : Never<`Excess property '${K & string}' not allowed as the target is an exact type`> } : T : diff --git a/tests/baselines/reference/self-types-exact.js b/tests/baselines/reference/self-types-exact.js index 2232aba4acb4f..40657414edc5f 100644 --- a/tests/baselines/reference/self-types-exact.js +++ b/tests/baselines/reference/self-types-exact.js @@ -10,17 +10,23 @@ f(() => ({ y: 1 })) -type Exact = +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 + ? (...a: _Exact) => _Exact : T : A extends object ? T extends object ? { [K in keyof A]: - K extends keyof T ? Exact : + K extends keyof T ? _Exact : Never<`Excess property '${K & string}' not allowed as the target is an exact type`> } : T : diff --git a/tests/baselines/reference/self-types-exact.symbols b/tests/baselines/reference/self-types-exact.symbols index 2d01af7f2bac9..19f354e8eee89 100644 --- a/tests/baselines/reference/self-types-exact.symbols +++ b/tests/baselines/reference/self-types-exact.symbols @@ -28,73 +28,84 @@ f(() => ({ })) -type Exact = +type Exact = >Exact : Symbol(Exact, Decl(self-types-exact.ts, 9, 3)) >T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) ->A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) - A extends T ->A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) + _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, 11, 11)) +>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, 11, 13)) ->a : Symbol(a, Decl(self-types-exact.ts, 14, 21)) ->Aa : Symbol(Aa, Decl(self-types-exact.ts, 14, 32)) ->Ar : Symbol(Ar, Decl(self-types-exact.ts, 14, 45)) +>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, 11, 11)) ->a : Symbol(a, Decl(self-types-exact.ts, 15, 25)) ->Ea : Symbol(Ea, Decl(self-types-exact.ts, 15, 36)) ->Er : Symbol(Er, Decl(self-types-exact.ts, 15, 49)) - - ? (...a: Exact) => Exact ->a : Symbol(a, Decl(self-types-exact.ts, 16, 19)) ->Exact : Symbol(Exact, Decl(self-types-exact.ts, 9, 3)) ->Ea : Symbol(Ea, Decl(self-types-exact.ts, 15, 36)) ->Aa : Symbol(Aa, Decl(self-types-exact.ts, 14, 32)) ->Exact : Symbol(Exact, Decl(self-types-exact.ts, 9, 3)) ->Er : Symbol(Er, Decl(self-types-exact.ts, 15, 49)) ->Ar : Symbol(Ar, Decl(self-types-exact.ts, 14, 45)) +>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, 11, 11)) +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) A extends object ->A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) +>A : Symbol(A, Decl(self-types-exact.ts, 17, 14)) ? T extends object ->T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) ? { [K in keyof A]: ->K : Symbol(K, Decl(self-types-exact.ts, 20, 21)) ->A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) - - K extends keyof T ? Exact : ->K : Symbol(K, Decl(self-types-exact.ts, 20, 21)) ->T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) ->Exact : Symbol(Exact, Decl(self-types-exact.ts, 9, 3)) ->T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) ->K : Symbol(K, Decl(self-types-exact.ts, 20, 21)) ->A : Symbol(A, Decl(self-types-exact.ts, 11, 13)) ->K : Symbol(K, Decl(self-types-exact.ts, 20, 21)) +>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, 20, 21)) +>K : Symbol(K, Decl(self-types-exact.ts, 26, 21)) } : T : ->T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) T ->T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) +>T : Symbol(T, Decl(self-types-exact.ts, 17, 12)) : never : T ->T : Symbol(T, Decl(self-types-exact.ts, 11, 11)) +>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 index 0382429e8cc30..1ff441f0b4975 100644 --- a/tests/baselines/reference/self-types-exact.types +++ b/tests/baselines/reference/self-types-exact.types @@ -1,14 +1,14 @@ === 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> +>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 +>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; } @@ -36,8 +36,16 @@ f(() => ({ })) -type Exact = ->Exact : Exact +type Exact = +>Exact : Exact + + _Exact + +// TODO: doesn't work if written as,,, +// type Exact = ... + +type _Exact = +>_Exact : _Exact A extends T ? T extends unknown @@ -47,14 +55,14 @@ type Exact = ? T extends (...a: infer Ea) => infer Er >a : Ea - ? (...a: Exact) => Exact ->a : Exact + ? (...a: _Exact) => _Exact +>a : _Exact : T : A extends object ? T extends object ? { [K in keyof A]: - K extends keyof T ? Exact : + K extends keyof T ? _Exact : Never<`Excess property '${K & string}' not allowed as the target is an exact type`> } : T : diff --git a/tests/baselines/reference/self-types-json-simple.types b/tests/baselines/reference/self-types-json-simple.types index 178e8305deb8f..3858c5181dda0 100644 --- a/tests/baselines/reference/self-types-json-simple.types +++ b/tests/baselines/reference/self-types-json-simple.types @@ -1,6 +1,6 @@ === tests/cases/compiler/self-types-json-simple.ts === type Json = ->Json : string | number | boolean | { toJSON: () => string; } | (self extends unknown[] ? Json[] : self extends (...a: never[]) => unknown ? never : { [_ in keyof self]: Json; }) | (self extends (...a: never[]) => unknown ? never : never) +>Json : Json | string | number @@ -63,7 +63,7 @@ let t6: Json = new Map() let t7: Json = ["hello", undefined] >t7 : Json ->["hello", undefined] : string[] +>["hello", undefined] : "hello"[] >"hello" : "hello" >undefined : undefined diff --git a/tests/baselines/reference/self-types-json.errors.txt b/tests/baselines/reference/self-types-json.errors.txt index 47ade9cd2f3e7..0441cdb9ac196 100644 --- a/tests/baselines/reference/self-types-json.errors.txt +++ b/tests/baselines/reference/self-types-json.errors.txt @@ -1,5 +1,5 @@ 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,5): error TS18051: Type '() => string' is not assignable to type 'Json', as it is a function +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. @@ -18,8 +18,9 @@ tests/cases/compiler/self-types-json.ts(18,5): error TS18051: Type '[string, und !!! 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 @@ -28,7 +29,7 @@ tests/cases/compiler/self-types-json.ts(18,5): error TS18051: Type '[string, und let t5: Json = { toJSON: () => "hello" } - let t6: Json = new Map() + 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} ~~~ diff --git a/tests/baselines/reference/self-types-json.js b/tests/baselines/reference/self-types-json.js index 1dedc23841449..d3dd61ab02185 100644 --- a/tests/baselines/reference/self-types-json.js +++ b/tests/baselines/reference/self-types-json.js @@ -14,7 +14,7 @@ let t4: Json = { let t5: Json = { toJSON: () => "hello" } -let t6: Json = new Map() +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] @@ -88,7 +88,7 @@ var t4 = { var t5 = { toJSON: function () { return "hello"; } }; -var t6 = new Map(); +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 index 3ea205f55a9c3..ee9ae183ce803 100644 --- a/tests/baselines/reference/self-types-json.symbols +++ b/tests/baselines/reference/self-types-json.symbols @@ -42,7 +42,7 @@ let t5: Json = { toJSON: () => "hello" >toJSON : Symbol(toJSON, Decl(self-types-json.ts, 12, 16)) } -let t6: Json = new Map() +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)) diff --git a/tests/baselines/reference/self-types-json.types b/tests/baselines/reference/self-types-json.types index 928e5c93fa420..b0370400d21fe 100644 --- a/tests/baselines/reference/self-types-json.types +++ b/tests/baselines/reference/self-types-json.types @@ -42,7 +42,7 @@ let t5: Json = { >() => "hello" : () => string >"hello" : "hello" } -let t6: Json = new Map() +let t6: Json = new Map() // TODO: fourslash doesn't seem to include Map >t6 : Json >new Map() : any >Map : any diff --git a/tests/baselines/reference/self-types-keyof.errors.txt b/tests/baselines/reference/self-types-keyof.errors.txt index d7c4a187161f8..bcced2f0816e5 100644 --- a/tests/baselines/reference/self-types-keyof.errors.txt +++ b/tests/baselines/reference/self-types-keyof.errors.txt @@ -1,10 +1,8 @@ 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(17,5): error TS2322: Type '{ a: number; } extends { [_ in KeyOf<{ a: number; }>]: infer X; } ? X : never' is not assignable to type 'number'. - Type 'unknown' is not assignable to type 'number'. -tests/cases/compiler/self-types-keyof.ts(17,33): error TS2345: Argument of type 'string' is not assignable to parameter of type 'KeyOf<{ 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 (3 errors) ==== +==== tests/cases/compiler/self-types-keyof.ts (2 errors) ==== // Implementing index types without index types type KeyOf = @@ -23,13 +21,10 @@ tests/cases/compiler/self-types-keyof.ts(17,33): error TS2345: Argument of type >(t: T, k: K) => T extends { [_ in K]: infer X } ? X : never - let t3: number = get({ a: 10 }, "a" as "a") - ~~ -!!! error TS2322: Type '{ a: number; } extends { [_ in KeyOf<{ a: number; }>]: infer X; } ? X : never' is not assignable to type 'number'. -!!! error TS2322: Type 'unknown' is not assignable to type 'number'. - ~~~~~~~~~~ -!!! error TS2345: Argument of type 'string' is not assignable to parameter of type 'KeyOf<{ a: number; }>'. - // TODO?: this should compile + 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 index 38eb5b2afdef0..0d253326a09f1 100644 --- a/tests/baselines/reference/self-types-keyof.js +++ b/tests/baselines/reference/self-types-keyof.js @@ -15,8 +15,8 @@ declare const get: >(t: T, k: K) => T extends { [_ in K]: infer X } ? X : never -let t3: number = get({ a: 10 }, "a" as "a") -// TODO?: this should compile +let t3: number = get({ a: 10 }, "a") +let t4 = get({ a: 10 }, "b") export {} @@ -28,3 +28,4 @@ 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 index a9c8c54731390..d3cd44978768f 100644 --- a/tests/baselines/reference/self-types-keyof.symbols +++ b/tests/baselines/reference/self-types-keyof.symbols @@ -49,12 +49,15 @@ declare const get: >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" as "a") +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)) -// TODO?: this should compile +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 index 468f369518862..da8047e041ec4 100644 --- a/tests/baselines/reference/self-types-keyof.types +++ b/tests/baselines/reference/self-types-keyof.types @@ -29,17 +29,23 @@ declare const get: T extends { [_ in K]: infer X } ? X : never -let t3: number = get({ a: 10 }, "a" as "a") +let t3: number = get({ a: 10 }, "a") >t3 : number ->get({ a: 10 }, "a" as "a") : { a: number; } extends { [_ in KeyOf<{ a: number; }>]: infer X; } ? X : never +>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" as "a" : "a" >"a" : "a" -// TODO?: this should compile +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.types b/tests/baselines/reference/self-types-mapped.types index 02fef18af1c72..780f1b87053fd 100644 --- a/tests/baselines/reference/self-types-mapped.types +++ b/tests/baselines/reference/self-types-mapped.types @@ -12,7 +12,7 @@ type User = } type _Partial = Mapped}>`> ->_Partial : _Partial +>_Partial : Mapped"> interface Mappers { _Partial: A[K & keyof A] | undefined } >_Partial : A[K & keyof A] @@ -56,7 +56,7 @@ let t02: _Partial = { } type _Omit = Mapped, "_Omit", T, `_Omit<${Print}, ${Print}>`> ->_Omit : _Omit +>_Omit : Mapped, "_Omit", T, "_Omit"> interface Mappers { _Omit: A[K & keyof A] } >_Omit : A[K & keyof A] @@ -88,7 +88,7 @@ let t12: _Omit = { } type FlipValues = ->FlipValues : FlipValues +>FlipValues : Mapped"> Mapped}, ${Print}, ${Print}>`> interface Mappers diff --git a/tests/baselines/reference/self-types-non-zero-number.types b/tests/baselines/reference/self-types-non-zero-number.types index 5d248342d0cb5..b4300f3ea3067 100644 --- a/tests/baselines/reference/self-types-non-zero-number.types +++ b/tests/baselines/reference/self-types-non-zero-number.types @@ -1,6 +1,6 @@ === tests/cases/compiler/self-types-non-zero-number.ts === type NonZeroNumber = ->NonZeroNumber : self extends number ? self extends 0 ? never : self : number +>NonZeroNumber : NonZeroNumber self extends number ? self extends 0 diff --git a/tests/baselines/reference/self-types-probability.types b/tests/baselines/reference/self-types-probability.types index fd3990d105702..2b3b541391d8f 100644 --- a/tests/baselines/reference/self-types-probability.types +++ b/tests/baselines/reference/self-types-probability.types @@ -64,7 +64,7 @@ type T1 = Assert >false : false type Probability = ->Probability : self extends number ? IsProbability extends true ? self : never : number +>Probability : Probability self extends number ? IsProbability extends true 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.types b/tests/baselines/reference/self-types-state-machine.types index 0813afae5450f..902e0c1326562 100644 --- a/tests/baselines/reference/self-types-state-machine.types +++ b/tests/baselines/reference/self-types-state-machine.types @@ -1,6 +1,6 @@ === tests/cases/compiler/self-types-state-machine.ts === type StateMachine = ->StateMachine : { [S in keyof self]: { [E in keyof self[S]]: keyof self; }; } +>StateMachine : StateMachine { [S in keyof self]: { [E in keyof self[S]]: keyof self } } diff --git a/tests/baselines/reference/self-types-string-literal.types b/tests/baselines/reference/self-types-string-literal.types index e60009f59d3d3..932a6627565cb 100644 --- a/tests/baselines/reference/self-types-string-literal.types +++ b/tests/baselines/reference/self-types-string-literal.types @@ -1,6 +1,6 @@ === tests/cases/compiler/self-types-string-literal.ts === type StringLiteral = ->StringLiteral : self extends string ? string extends self ? never : self : string +>StringLiteral : StringLiteral self extends string ? string extends self From bf8b3ab38838bcc4da2823bc3b29d6c0ce6cf8bf Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Fri, 6 Jan 2023 23:05:46 +0000 Subject: [PATCH 20/30] fix completions order --- src/harness/fourslashInterfaceImpl.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index a851ad2165729..f8190fcf35e6a 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1085,14 +1085,14 @@ export namespace Completion { "number", "object", "readonly", + "self", "string", "symbol", "true", "undefined", "unique", "unknown", - "self", - "void", + "void" ].map(keywordEntry); export function sorted(entries: readonly ExpectedCompletionEntry[]): readonly ExpectedCompletionEntry[] { @@ -1263,13 +1263,13 @@ export namespace Completion { case "readonly": case "number": case "object": + case "self": case "string": case "symbol": case "type": case "unique": case "override": case "unknown": - case "self": case "global": case "bigint": return false; @@ -1400,6 +1400,7 @@ export namespace Completion { "readonly", "return", "satisfies", + "self", "string", "super", "switch", @@ -1412,7 +1413,6 @@ export namespace Completion { "typeof", "unique", "unknown", - "self", "var", "void", "while", @@ -1616,6 +1616,7 @@ export namespace Completion { "readonly", "return", "satisfies", + "self", "string", "super", "switch", @@ -1628,7 +1629,6 @@ export namespace Completion { "typeof", "unique", "unknown", - "self", "var", "void", "while", From 90c9032d7b53b32c227da796e7f08a33ae3e9d32 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Fri, 6 Jan 2023 23:33:43 +0000 Subject: [PATCH 21/30] accept completions and other chore baseline --- ...hExportedLocalVarsOfTheSameName.errors.txt | 12 +- .../reference/api/tsserverlibrary.d.ts | 601 ++++++++++-------- tests/baselines/reference/api/typescript.d.ts | 601 ++++++++++-------- .../completionsCommentsClass.baseline | 12 + .../completionsCommentsClassMembers.baseline | 24 + ...completionsCommentsCommentParsing.baseline | 24 + ...letionsCommentsFunctionExpression.baseline | 24 + ...ed-from-two-different-drives-of-windows.js | 6 + .../caches-importability-within-a-file.js | 6 + .../caches-module-specifiers-within-a-file.js | 6 + ...date-the-cache-when-new-files-are-added.js | 6 + ...n-in-contained-node_modules-directories.js | 6 + ...he-cache-when-local-packageJson-changes.js | 6 + ...-when-module-resolution-settings-change.js | 6 + ...ache-when-symlinks-are-added-or-removed.js | 6 + ...-the-cache-when-user-preferences-change.js | 18 + .../getSupportedCodeFixes-can-be-proxied.js | 3 + .../projects/tsconfig-script-block-support.js | 12 + 18 files changed, 827 insertions(+), 552 deletions(-) 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..6c4c09697b4ac 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; @@ -6631,56 +6632,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 +6919,19 @@ declare namespace ts { baseType: Type; constraint: Type; } + interface SelfedType extends InstantiableType { + type: Type; + selfType: Type; + instantiations: Map; + } + interface NeverWithErrorType extends InstantiableType, IntrinsicType { + errorType: Type; + } + interface PrintType extends InstantiableType { + type: Type; + flagType: Type; + resolvedStringLiteralType: StringLiteralType; + } enum SignatureKind { Call = 0, Construct = 1 diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 7c3088b485c5d..c89d40478bc12 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; @@ -2696,56 +2697,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 +2984,19 @@ declare namespace ts { baseType: Type; constraint: Type; } + interface SelfedType extends InstantiableType { + type: Type; + selfType: Type; + instantiations: Map; + } + interface NeverWithErrorType extends InstantiableType, IntrinsicType { + errorType: Type; + } + interface PrintType extends InstantiableType { + type: Type; + flagType: Type; + resolvedStringLiteralType: StringLiteralType; + } enum SignatureKind { Call = 0, Construct = 1 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/tsserver/completions/works-when-files-are-included-from-two-different-drives-of-windows.js b/tests/baselines/reference/tsserver/completions/works-when-files-are-included-from-two-different-drives-of-windows.js index 723c10460b08b..c03a3d8c6599a 100644 --- a/tests/baselines/reference/tsserver/completions/works-when-files-are-included-from-two-different-drives-of-windows.js +++ b/tests/baselines/reference/tsserver/completions/works-when-files-are-included-from-two-different-drives-of-windows.js @@ -476,6 +476,12 @@ Info 37 [00:01:41.000] response: "kindModifiers": "", "sortText": "15" }, + { + "name": "self", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, { "name": "super", "kind": "keyword", 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", From bc980f1c237876ee85a0b154ece3e7036e3cc33e Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Fri, 6 Jan 2023 23:52:43 +0000 Subject: [PATCH 22/30] fix lint --- src/compiler/checker.ts | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 52c939bd08004..caefdb959855b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -347,8 +347,8 @@ import { hasAccessorModifier, hasAmbientModifier, hasContextSensitiveParameters, - HasDecorators, hasDecorators, + HasDecorators, hasDynamicName, hasEffectiveModifier, hasEffectiveModifiers, @@ -357,8 +357,8 @@ import { hasExtension, HasIllegalDecorators, HasIllegalModifiers, - HasInitializer, hasInitializer, + HasInitializer, hasJSDocNodes, hasJSDocParameterTags, hasJsonModuleEmitEnabled, @@ -892,6 +892,7 @@ import { SatisfiesExpression, ScriptKind, ScriptTarget, + SelfedType, SetAccessorDeclaration, setCommentRange, setEmitFlags, @@ -1033,7 +1034,6 @@ import { WideningContext, WithStatement, YieldExpression, - SelfedType, } from "./_namespaces/ts"; import * as performance from "./_namespaces/ts.performance"; import * as moduleSpecifiers from "./_namespaces/ts.moduleSpecifiers"; @@ -11784,7 +11784,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (node.kind === SyntaxKind.SelfKeyword) return true; }); if (containsSelfType) { - type = createSelfedType(type, links.selfType!) + type = createSelfedType(type, links.selfType!); } if (popTypeResolution()) { @@ -13533,7 +13533,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getBaseConstraint(getSubstitutionIntersection(t as SubstitutionType)); } if (t.flags & TypeFlags.Selfed) { - return getBaseConstraint((t as SelfedType).type) + return getBaseConstraint((t as SelfedType).type); } return t; } @@ -16867,15 +16867,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const selfType = createTypeParameter() as TypeParameter & IntrinsicType; selfType.intrinsicName = "self"; selfType.flags |= TypeFlags.Self; - return selfType + 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 + const selfedType = createType(TypeFlags.Selfed) as SelfedType; + selfedType.type = type; + selfedType.selfType = selfType; + selfedType.instantiations = new Map(); + return selfedType; } function createNeverWithErrorType(errorType: Type) { @@ -18807,7 +18807,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return createSelfedType( instantiateType((type as SelfedType).type, mapper), (type as SelfedType).selfType - ) + ); } if (flags & TypeFlags.NeverWithError) { return createNeverWithErrorType(instantiateType((type as NeverWithErrorType).errorType, mapper)); @@ -19780,8 +19780,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter): boolean { - source = instantiateSelfTypeIfRequired(source, target) - target = instantiateSelfTypeIfRequired(target, source) + source = instantiateSelfTypeIfRequired(source, target); + target = instantiateSelfTypeIfRequired(target, source); const s = source.flags; const t = target.flags; if (t & TypeFlags.AnyOrUnknown || s & TypeFlags.Never || source === wildcardType) return true; @@ -19825,8 +19825,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isTypeRelatedTo(source: Type, target: Type, relation: Map) { - source = instantiateSelfTypeIfRequired(source, target) - target = instantiateSelfTypeIfRequired(target, source) + source = instantiateSelfTypeIfRequired(source, target); + target = instantiateSelfTypeIfRequired(target, source); if (isFreshLiteralType(source)) { source = (source as FreshableType).regularType; } @@ -20273,8 +20273,8 @@ 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 = instantiateSelfTypeIfRequired(originalSource, originalTarget) - originalTarget = instantiateSelfTypeIfRequired(originalTarget, originalSource) + originalSource = instantiateSelfTypeIfRequired(originalSource, originalTarget); + originalTarget = instantiateSelfTypeIfRequired(originalTarget, originalSource); // 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) { From 8ffb161d7058b18c7d74949619ff9b5921dee8ba Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Sat, 7 Jan 2023 00:13:49 +0000 Subject: [PATCH 23/30] fix external .d.ts --- src/compiler/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index d639ac06fff36..ad2a05e799fdf 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -6618,6 +6618,7 @@ export interface SelfedType extends InstantiableType { instantiations: Map } +/** @internal */ export interface NeverWithErrorType extends InstantiableType, IntrinsicType { errorType: Type } From d3e64a53b76780ec1dd074076a2d18e2cfa932df Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Sat, 7 Jan 2023 00:28:47 +0000 Subject: [PATCH 24/30] recognise "self" as a type at missing places --- src/compiler/checker.ts | 3 ++- src/services/completions.ts | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index caefdb959855b..4365dac811aeb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3584,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 { @@ -41391,6 +41391,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { case "symbol": case "void": case "object": + case "self": error(name, message, name.escapedText as string); } } 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: From 8b0e98045be2f4b6dbe72aa6b1c9c08b00625f07 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Sat, 7 Jan 2023 01:15:14 +0000 Subject: [PATCH 25/30] accept completions baseline --- ...les-are-included-from-two-different-drives-of-windows.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/baselines/reference/tsserver/completions/works-when-files-are-included-from-two-different-drives-of-windows.js b/tests/baselines/reference/tsserver/completions/works-when-files-are-included-from-two-different-drives-of-windows.js index c03a3d8c6599a..723c10460b08b 100644 --- a/tests/baselines/reference/tsserver/completions/works-when-files-are-included-from-two-different-drives-of-windows.js +++ b/tests/baselines/reference/tsserver/completions/works-when-files-are-included-from-two-different-drives-of-windows.js @@ -476,12 +476,6 @@ Info 37 [00:01:41.000] response: "kindModifiers": "", "sortText": "15" }, - { - "name": "self", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, { "name": "super", "kind": "keyword", From 0eef6df9d8c282f27ed68acdc5b5e13dc7ee3259 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Sat, 7 Jan 2023 01:15:44 +0000 Subject: [PATCH 26/30] accept external .d.ts baseline --- tests/baselines/reference/api/tsserverlibrary.d.ts | 3 --- tests/baselines/reference/api/typescript.d.ts | 3 --- 2 files changed, 6 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 6c4c09697b4ac..5796d6e0534ba 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6924,9 +6924,6 @@ declare namespace ts { selfType: Type; instantiations: Map; } - interface NeverWithErrorType extends InstantiableType, IntrinsicType { - errorType: Type; - } interface PrintType extends InstantiableType { type: Type; flagType: Type; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c89d40478bc12..c61685f09633c 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2989,9 +2989,6 @@ declare namespace ts { selfType: Type; instantiations: Map; } - interface NeverWithErrorType extends InstantiableType, IntrinsicType { - errorType: Type; - } interface PrintType extends InstantiableType { type: Type; flagType: Type; From 9ecf8a88fe0039830d6b11945d828c1ccf2c2709 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Sat, 7 Jan 2023 18:49:12 +0000 Subject: [PATCH 27/30] make self instantiation more resilient --- src/compiler/checker.ts | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4365dac811aeb..1fbe5060ae765 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -18815,19 +18815,29 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return type; } - function instantiateSelfTypeIfRequired(source: Type, target: Type) { - if (!(source.flags & TypeFlags.Selfed)) return source; + 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) { - if (getTypeId(target) === getTypeId(source)) return source; - return (source as SelfedType).type; + return [source, instantiateSelfType(target as SelfedType, source)] } + return Debug.fail() + } - const sourceSelfed = source as SelfedType; - if (sourceSelfed.instantiations.has(getTypeId(target).toString())) { - return sourceSelfed.instantiations.get(getTypeId(target).toString())!; + function instantiateSelfType(selfed: SelfedType, self: Type) { + if (selfed.instantiations.has(getTypeId(self).toString())) { + return selfed.instantiations.get(getTypeId(self).toString())!; } - const instantiated = instantiateType(sourceSelfed.type, makeUnaryTypeMapper(sourceSelfed.selfType, target)); - sourceSelfed.instantiations.set(getTypeId(target).toString(), instantiated); + const instantiated = instantiateType(selfed.type, makeUnaryTypeMapper(selfed.selfType, self)); + selfed.instantiations.set(getTypeId(self).toString(), instantiated); return instantiated; } @@ -19780,8 +19790,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isSimpleTypeRelatedTo(source: Type, target: Type, relation: Map, errorReporter?: ErrorReporter): boolean { - source = instantiateSelfTypeIfRequired(source, target); - target = instantiateSelfTypeIfRequired(target, source); + [source, target] = instantiateSelfTypesIfRequired(source, target); const s = source.flags; const t = target.flags; if (t & TypeFlags.AnyOrUnknown || s & TypeFlags.Never || source === wildcardType) return true; @@ -19825,8 +19834,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function isTypeRelatedTo(source: Type, target: Type, relation: Map) { - source = instantiateSelfTypeIfRequired(source, target); - target = instantiateSelfTypeIfRequired(target, source); + [source, target] = instantiateSelfTypesIfRequired(source, target); if (isFreshLiteralType(source)) { source = (source as FreshableType).regularType; } @@ -20273,8 +20281,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 = instantiateSelfTypeIfRequired(originalSource, originalTarget); - originalTarget = instantiateSelfTypeIfRequired(originalTarget, originalSource); + [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) { From 9815389c607e7f4a2e9bd1d706449bff94de95da Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Sat, 7 Jan 2023 21:11:26 +0000 Subject: [PATCH 28/30] create an emit flag to not escape string literals --- src/compiler/checker.ts | 30 ++++++++++++++++++++---------- src/compiler/emitter.ts | 3 ++- src/compiler/types.ts | 6 +++++- src/compiler/utilities.ts | 3 ++- 4 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1fbe5060ae765..bc028f097e2b5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6042,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"); @@ -6061,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); @@ -6244,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; @@ -6430,6 +6437,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { 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) { @@ -16909,9 +16917,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const type = getStringLiteralType(typeToString( printType.type, /* enclosingDeclaration */ undefined, - isTypeSubtypeOf(getStringLiteralType("InTypeAlias"), printType.flagType) + getTypeToStringDefaultFlags() | + (isTypeSubtypeOf(getStringLiteralType("InTypeAlias"), printType.flagType) ? TypeFormatFlags.InTypeAlias - : TypeFormatFlags.None + : 0) )); printType.resolvedStringLiteralType = type; @@ -20150,13 +20159,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!every(errorTypes, t => !!(t.flags & TypeFlags.StringLike))) return reportNonCustom(); while (errorTypes.length > 0) { - reportError(Diagnostics._0, - typeToString(errorTypes.pop()!) + reportError( + Diagnostics._0, + typeToString( + errorTypes.pop()!, + /* enclosingDeclaration */ undefined, + TypeFormatFlags.NoStringLiteralEscaping | getTypeToStringDefaultFlags() + ) .slice(1,-1) - .replace(/\\"/g, '"') - .replace(/\\'/g, "'") - .replace(/\\\\/g, "\\") - .replace(/\\n/g, "\n") ); } return; 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/types.ts b/src/compiler/types.ts index ad2a05e799fdf..dcf5e548fc2a8 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5293,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, @@ -5353,13 +5354,15 @@ export const enum TypeFormatFlags { InElementType = 1 << 21, // Writing an array or union element type 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 { @@ -7916,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 55169e9f0ea43..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) { From ecfa9ed5dbe417e936bc34b6e016adbb960a747f Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Sat, 7 Jan 2023 21:50:42 +0000 Subject: [PATCH 29/30] fix lint --- src/compiler/checker.ts | 8 ++++---- src/compiler/types.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bc028f097e2b5..6ac5117d47caf 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6062,7 +6062,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function getTypeToStringDefaultFlags() { - return TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope + return TypeFormatFlags.AllowUniqueESSymbolType | TypeFormatFlags.UseAliasDefinedOutsideCurrentScope; } function getTypeNamesForErrorDisplay(left: Type, right: Type): [string, string] { @@ -18833,12 +18833,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return [(source as SelfedType).type, (target as SelfedType).type]; } if (source.flags & TypeFlags.Selfed) { - return [instantiateSelfType(source as SelfedType, target), target] + return [instantiateSelfType(source as SelfedType, target), target]; } if (target.flags & TypeFlags.Selfed) { - return [source, instantiateSelfType(target as SelfedType, source)] + return [source, instantiateSelfType(target as SelfedType, source)]; } - return Debug.fail() + return Debug.fail(); } function instantiateSelfType(selfed: SelfedType, self: Type) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index dcf5e548fc2a8..8f52ebea8aa0b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5354,7 +5354,7 @@ export const enum TypeFormatFlags { InElementType = 1 << 21, // Writing an array or union element type 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 From 303ea0030e07059b5b555b6acaab9820be48b221 Mon Sep 17 00:00:00 2001 From: Devansh Jethmalani Date: Sat, 7 Jan 2023 22:10:12 +0000 Subject: [PATCH 30/30] accept new public api baseline --- tests/baselines/reference/api/tsserverlibrary.d.ts | 7 +++++-- tests/baselines/reference/api/typescript.d.ts | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 5796d6e0534ba..2f3a52375ea86 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -6429,6 +6429,7 @@ declare namespace ts { UseSingleQuotesForStringLiteralType = 268435456, NoTypeReduction = 536870912, OmitThisParameter = 33554432, + NoStringLiteralEscaping = -2147483648, AllowThisInObjectLiteral = 32768, AllowQualifiedNameInPlaceOfIdentifier = 65536, /** @deprecated AllowQualifedNameInPlaceOfIdentifier. Use AllowQualifiedNameInPlaceOfIdentifier instead. */ @@ -6467,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, @@ -7471,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 c61685f09633c..d01a8c9e23726 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2494,6 +2494,7 @@ declare namespace ts { UseSingleQuotesForStringLiteralType = 268435456, NoTypeReduction = 536870912, OmitThisParameter = 33554432, + NoStringLiteralEscaping = -2147483648, AllowThisInObjectLiteral = 32768, AllowQualifiedNameInPlaceOfIdentifier = 65536, /** @deprecated AllowQualifedNameInPlaceOfIdentifier. Use AllowQualifiedNameInPlaceOfIdentifier instead. */ @@ -2532,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, @@ -3536,7 +3538,8 @@ declare namespace ts { NoHoisting = 4194304, HasEndOfDeclarationMarker = 8388608, Iterator = 16777216, - NoAsciiEscaping = 33554432 + NoAsciiEscaping = 33554432, + NoStringEscaping = -2147483648 } interface EmitHelperBase { readonly name: string;