From 6c2105a932acfa73bef692b13ecef394e73d8530 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 29 Jan 2024 13:26:25 -0800 Subject: [PATCH 01/18] Heavy WIP Probably need automatic deferred type queries to handle this. --- src/compiler/checker.ts | 430 +++++++++++++++--- src/compiler/types.ts | 148 +----- src/compiler/utilities.ts | 36 +- src/tsconfig-base.json | 4 +- ...rrorDeferredTypeReferenceSignatureCycle.ts | 14 + 5 files changed, 425 insertions(+), 207 deletions(-) create mode 100644 tests/cases/compiler/noCircularityErrorDeferredTypeReferenceSignatureCycle.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 2658e1bcac8c8..a97875e197979 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -139,6 +139,7 @@ import { DiagnosticAndArguments, DiagnosticArguments, DiagnosticCategory, + DiagnosticCollection, DiagnosticMessage, DiagnosticMessageChain, DiagnosticRelatedInformation, @@ -827,7 +828,6 @@ import { LiteralTypeNode, map, mapDefined, - MappedSymbol, MappedType, MappedTypeNode, MatchingKeys, @@ -838,6 +838,7 @@ import { MethodSignature, minAndMax, MinusToken, + ModeAwareCacheKey, Modifier, ModifierFlags, modifiersToFlags, @@ -865,10 +866,10 @@ import { NodeCheckFlags, NodeFlags, nodeHasName, + NodeId, nodeIsMissing, nodeIsPresent, nodeIsSynthesized, - NodeLinks, nodeStartsNewLexicalEnvironment, NodeWithTypeArguments, NonNullChain, @@ -939,7 +940,6 @@ import { resolvingEmptyArray, RestTypeNode, ReturnStatement, - ReverseMappedSymbol, ReverseMappedType, sameMap, SatisfiesExpression, @@ -992,7 +992,6 @@ import { SymbolFlags, SymbolFormatFlags, SymbolId, - SymbolLinks, symbolName, SymbolTable, SymbolTracker, @@ -1016,9 +1015,6 @@ import { tokenToString, tracing, TracingNode, - TrackedSymbol, - TransientSymbol, - TransientSymbolLinks, tryAddToSet, tryCast, tryExtractTSExtension, @@ -1377,14 +1373,169 @@ const intrinsicTypeKinds: ReadonlyMap = new Map(Objec NoInfer: IntrinsicTypeKind.NoInfer, })); -const SymbolLinks = class implements SymbolLinks { +class SaveableLinks { + save() { + // TODO: Optimize perf to delay copies until necessary, and to copy only changes. + // TODO: Some nested deep caches like `specifierCache` or more meaningfully + // `extendedContainersByFile` should really be deep copied/restored, since they may refernce + // Symbol information for discarded speculative symbols. + // TODO: The return type is a `SaveableLinks`, which is an abuse of a type system bug - + // the spread will peel away the prototype - there won't be `.save` or `.restore` methods on it. + return { ...this }; + } + restore(state: T) { + for (const k in state) { + if (Object.prototype.hasOwnProperty.call(state, k)) { + this[k as keyof this] = state[k] as unknown as this[keyof this]; + } + } + for (const k in this) { + if (!Object.prototype.hasOwnProperty.call(state, k)) { + // TODO: `delete` has perf implications, but we really do want to *remove* the keys we added + // Still, `= undefined` might make future copies unnecessarily heavier, but should otherwise be fine. + // Should choose between them based on perf testing. + this[k] = undefined!; + } + } + } +} + +/** @internal */ +const enum EnumKind { + Numeric, // Numeric enum (each member has a TypeFlags.Enum type) + Literal, // Literal enum (each member has a TypeFlags.EnumLiteral type) +} + +// dprint-ignore +/** @internal */ +class SymbolLinks extends SaveableLinks { declare _symbolLinksBrand: any; + declare immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead. + declare aliasTarget?: Symbol; // Resolved (non-alias) target of an alias + declare target?: Symbol; // Original version of an instantiated symbol + declare type?: Type; // Type of value symbol + declare writeType?: Type; // Type of value symbol in write contexts + declare nameType?: Type; // Type associated with a late-bound symbol + declare uniqueESSymbolType?: Type; // UniqueESSymbol type for a symbol + declare declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter + declare typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic) + declare outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type + declare instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) + declare aliasSymbol?: Symbol; // Alias associated with generic type alias instantiation + declare aliasTypeArguments?: readonly Type[] // Alias type arguments (if any) + declare inferredClassSymbol?: Map; // Symbol of an inferred ES5 constructor function + declare mapper?: TypeMapper; // Type mapper for instantiation alias + declare referenced?: boolean; // True if alias symbol has been referenced as a value that can be emitted + declare constEnumReferenced?: boolean; // True if alias symbol resolves to a const enum and is referenced as a value ('referenced' will be false) + declare containingType?: UnionOrIntersectionType; // Containing union or intersection type for synthetic property + declare leftSpread?: Symbol; // Left source for synthetic spread property + declare rightSpread?: Symbol; // Right source for synthetic spread property + declare syntheticOrigin?: Symbol; // For a property on a mapped or spread type, points back to the original property + declare isDiscriminantProperty?: boolean; // True if discriminant synthetic property + declare resolvedExports?: SymbolTable; // Resolved exports of module or combined early- and late-bound static members of a class. + declare resolvedMembers?: SymbolTable; // Combined early- and late-bound members of a symbol + declare exportsChecked?: boolean; // True if exports of external module have been checked + declare typeParametersChecked?: boolean; // True if type parameters of merged class and interface declarations have been checked. + declare isDeclarationWithCollidingName?: boolean; // True if symbol is block scoped redeclaration + declare bindingElement?: BindingElement; // Binding element associated with property symbol + declare exportsSomeValue?: boolean; // True if module exports some value (not just types) + declare enumKind?: EnumKind; // Enum declaration classification + declare originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol` + declare lateSymbol?: Symbol; // Late-bound symbol for a computed property + declare specifierCache?: Map; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings + declare extendedContainers?: Symbol[]; // Containers (other than the parent) which this symbol is aliased in + declare extendedContainersByFile?: Map; // Containers (other than the parent) which this symbol is aliased in + declare variances?: VarianceFlags[]; // Alias symbol type argument variance cache + declare deferralConstituents?: Type[]; // Calculated list of constituents for a deferred type + declare deferralWriteConstituents?: Type[]; // Constituents of a deferred `writeType` + declare deferralParent?: Type; // Source union/intersection of a deferred type + declare cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target + declare typeOnlyDeclaration?: TypeOnlyAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs + declare typeOnlyExportStarMap?: Map<__String, ExportDeclaration & { readonly isTypeOnly: true, readonly moduleSpecifier: Expression }>; // Set on a module symbol when some of its exports were resolved through a 'export type * from "mod"' declaration + declare typeOnlyExportStarName?: __String; // Set to the name of the symbol re-exported by an 'export type *' declaration, when different from the symbol name + declare isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor + declare tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label + declare accessibleChainCache?: Map; + declare filteredIndexSymbolCache?: Map //Symbol with applicable declarations }; -function NodeLinks(this: NodeLinks) { - this.flags = NodeCheckFlags.None; +/** @internal */ +interface TransientSymbolLinks extends SymbolLinks { + checkFlags: CheckFlags; } +/** @internal */ +export interface TransientSymbol extends Symbol { + links: TransientSymbolLinks; +} + +interface MappedSymbolLinks extends TransientSymbolLinks { + mappedType: MappedType; + keyType: Type; +} + +interface MappedSymbol extends TransientSymbol { + links: MappedSymbolLinks; +} + +interface ReverseMappedSymbolLinks extends TransientSymbolLinks { + propertyType: Type; + mappedType: MappedType; + constraintType: IndexType; +} + +interface ReverseMappedSymbol extends TransientSymbol { + links: ReverseMappedSymbolLinks; +} + +type TrackedSymbol = [symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags]; + +interface SerializedTypeEntry { + node: TypeNode; + truncating?: boolean; + addedLength: number; + trackedSymbols: readonly TrackedSymbol[] | undefined; +} + +// dprint-ignore +class NodeLinks extends SaveableLinks { + declare flags: NodeCheckFlags; // Set of flags specific to Node + declare resolvedType?: Type; // Cached type of type node + declare resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag + declare resolvedSignature?: Signature; // Cached signature of signature node or call expression + declare resolvedSymbol?: Symbol; // Cached name resolution result + declare resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result + declare effectsSignature?: Signature; // Signature with possible control flow effects + declare enumMemberValue?: string | number; // Constant value of enum member + declare isVisible?: boolean; // Is this node visible + declare containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference + declare hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context + declare jsxFlags?: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with + declare resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element + declare resolvedJsxElementAllAttributesType?: Type; // resolved all element attributes type of a JSX openinglike element + declare resolvedJSDocType?: Type; // Resolved type of a JSDoc type reference + declare switchTypes?: Type[]; // Cached array of switch case expression types + declare jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node + declare jsxImplicitImportContainer?: Symbol | false; // Resolved module symbol the implicit jsx import of this file should refer to + declare contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive + declare deferredNodes?: Set; // Set of nodes whose checking has been deferred + declare capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement + declare outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type + declare isExhaustive?: boolean | 0; // Is node an exhaustive switch statement (0 indicates in-process resolution) + declare skipDirectInference?: true; // Flag set by the API `getContextualType` call on a node when `Completions` is passed to force the checker to skip making inferences to a node's type + declare declarationRequiresScopeChange?: boolean; // Set by `useOuterVariableScopeInParameter` in checker when downlevel emit would change the name resolution scope inside of a parameter. + declare serializedTypes?: Map; // Collection of types serialized at this location + declare decoratorSignature?: Signature; // Signature for decorator as if invoked by the runtime. + declare spreadIndices?: { first: number | undefined, last: number | undefined }; // Indices of first and last spread elements in array literal + declare parameterInitializerContainsUndefined?: boolean; // True if this is a parameter declaration whose type annotation contains "undefined". + declare fakeScopeForSignatureDeclaration?: "params" | "typeParams"; // If present, this is a fake scope injected into an enclosing declaration chain. + declare assertionExpressionType?: Type; // Cached type of the expression of a type assertion + constructor() { + super(); + this.flags = NodeCheckFlags.None; + } +}; + /** @internal */ export function getNodeId(node: Node): number { if (!node.id) { @@ -1413,10 +1564,18 @@ export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums /** @internal */ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { + // List of all caches whose state should be saved and potentially restored on completion of a speculative typechecking operation + var speculativeCaches: (any[] | Map | Set | DiagnosticCollection)[] = []; + // Transient symbols store their links directly on them, so each transient symbol is also a small speculative cache. + // WeakRef is first supported in node 14 (our earliest test version) - unlike weakmap and weakset which are node 0.12 + // Do note that this works without WeakRefs, but would mean we can leak memory via unbounded transient symbol creation pretty easily. + // This has to be an array of weak refs and not a weak map or weak set because we need to iterate over them to attempt to save their state. + var transientSymbols: WeakRef[] = []; + // Why var? It avoids TDZ checks in the runtime which can be costly. // See: https://github.com/microsoft/TypeScript/issues/52924 /* eslint-disable no-var */ - var deferredDiagnosticsCallbacks: (() => void)[] = []; + var deferredDiagnosticsCallbacks: (() => void)[] = registerSpeculativeCache([]); var addLazyDiagnostic = (arg: () => void) => { deferredDiagnosticsCallbacks.push(arg); @@ -1936,29 +2095,29 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return res; } - var tupleTypes = new Map(); - var unionTypes = new Map(); - var unionOfUnionTypes = new Map(); - var intersectionTypes = new Map(); - var stringLiteralTypes = new Map(); - var numberLiteralTypes = new Map(); - var bigIntLiteralTypes = new Map(); - var enumLiteralTypes = new Map(); - var indexedAccessTypes = new Map(); - var templateLiteralTypes = new Map(); - var stringMappingTypes = new Map(); - var substitutionTypes = new Map(); - var subtypeReductionCache = new Map(); - var decoratorContextOverrideTypeCache = new Map(); - var cachedTypes = new Map(); - var evolvingArrayTypes: EvolvingArrayType[] = []; - var undefinedProperties: SymbolTable = new Map(); - var markerTypes = new Set(); + var tupleTypes = registerSpeculativeCache(new Map()); + var unionTypes = registerSpeculativeCache(new Map()); + var unionOfUnionTypes = registerSpeculativeCache(new Map()); + var intersectionTypes = registerSpeculativeCache(new Map()); + var stringLiteralTypes = registerSpeculativeCache(new Map()); + var numberLiteralTypes = registerSpeculativeCache(new Map()); + var bigIntLiteralTypes = registerSpeculativeCache(new Map()); + var enumLiteralTypes = registerSpeculativeCache(new Map()); + var indexedAccessTypes = registerSpeculativeCache(new Map()); + var templateLiteralTypes = registerSpeculativeCache(new Map()); + var stringMappingTypes = registerSpeculativeCache(new Map()); + var substitutionTypes = registerSpeculativeCache(new Map()); + var subtypeReductionCache = registerSpeculativeCache(new Map()); + var decoratorContextOverrideTypeCache = registerSpeculativeCache(new Map()); + var cachedTypes = registerSpeculativeCache(new Map()); + var evolvingArrayTypes: EvolvingArrayType[] = registerSpeculativeCache([]); + var undefinedProperties: SymbolTable = registerSpeculativeCache(new Map()); + var markerTypes = registerSpeculativeCache(new Set()); var unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String); var resolvingSymbol = createSymbol(0, InternalSymbolName.Resolving); - var unresolvedSymbols = new Map(); - var errorTypes = new Map(); + var unresolvedSymbols = registerSpeculativeCache(new Map()); + var errorTypes = registerSpeculativeCache(new Map()); // We specifically create the `undefined` and `null` types before any other types that can occur in // unions such that they are given low type IDs and occur first in the sorted list of union constituents. @@ -2073,7 +2232,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var enumNumberIndexInfo = createIndexInfo(numberType, stringType, /*isReadonly*/ true); - var iterationTypesCache = new Map(); // cache for common IterationTypes instances + var iterationTypesCache = registerSpeculativeCache(new Map()); // cache for common IterationTypes instances var noIterationTypes: IterationTypes = { get yieldType(): Type { return Debug.fail("Not supported"); @@ -2131,7 +2290,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } /** Key is "/path/to/a.ts|/path/to/b.ts". */ var amalgamatedDuplicates: Map | undefined; - var reverseMappedCache = new Map(); + var reverseMappedCache = registerSpeculativeCache(new Map()); var homomorphicMappedTypeInferenceStack: string[] = []; var ambientModulesCache: Symbol[] | undefined; /** @@ -2234,14 +2393,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var suggestionCount = 0; var maximumSuggestionCount = 10; var mergedSymbols: Symbol[] = []; - var symbolLinks: SymbolLinks[] = []; - var nodeLinks: NodeLinks[] = []; - var flowLoopCaches: Map[] = []; + var symbolLinks: SymbolLinks[] = registerSpeculativeCache([]); + var nodeLinks: NodeLinks[] = registerSpeculativeCache([]); + var flowLoopCaches: Map[] = registerSpeculativeCache([]); var flowLoopNodes: FlowNode[] = []; var flowLoopKeys: string[] = []; - var flowLoopTypes: Type[][] = []; - var sharedFlowNodes: FlowNode[] = []; - var sharedFlowTypes: FlowType[] = []; + var flowLoopTypes: Type[][] = registerSpeculativeCache([]); + var sharedFlowNodes: FlowNode[] = registerSpeculativeCache([]); + var sharedFlowTypes: FlowType[] = registerSpeculativeCache([]); var flowNodeReachable: (boolean | undefined)[] = []; var flowNodePostSuper: (boolean | undefined)[] = []; var potentialThisCollisions: Node[] = []; @@ -2251,20 +2410,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var potentialUnusedRenamedBindingElementsInTypes: BindingElement[] = []; var awaitedTypeStack: number[] = []; - var diagnostics = createDiagnosticCollection(); - var suggestionDiagnostics = createDiagnosticCollection(); + var diagnostics = registerSpeculativeCache(createDiagnosticCollection()); + var suggestionDiagnostics = registerSpeculativeCache(createDiagnosticCollection()); var typeofType = createTypeofType(); var _jsxNamespace: __String; var _jsxFactoryEntity: EntityName | undefined; - var subtypeRelation = new Map(); - var strictSubtypeRelation = new Map(); - var assignableRelation = new Map(); - var comparableRelation = new Map(); - var identityRelation = new Map(); - var enumRelation = new Map(); + var subtypeRelation = registerSpeculativeCache(new Map()); + var strictSubtypeRelation = registerSpeculativeCache(new Map()); + var assignableRelation = registerSpeculativeCache(new Map()); + var comparableRelation = registerSpeculativeCache(new Map()); + var identityRelation = registerSpeculativeCache(new Map()); + var enumRelation = registerSpeculativeCache(new Map()); var builtinGlobals = createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); @@ -2487,6 +2646,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const symbol = new Symbol(flags | SymbolFlags.Transient, name) as TransientSymbol; symbol.links = new SymbolLinks() as TransientSymbolLinks; symbol.links.checkFlags = checkFlags || CheckFlags.None; + transientSymbols.push(new WeakRef(symbol)); return symbol; } @@ -20878,18 +21038,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (!(checkMode & SignatureCheckMode.IgnoreReturnTypes)) { - // If a signature resolution is already in-flight, skip issuing a circularity error - // here and just use the `any` type directly - const targetReturnType = isResolvingReturnTypeOfSignature(target) ? anyType - : target.declaration && isJSConstructor(target.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(target.declaration.symbol)) - : getReturnTypeOfSignature(target); - if (targetReturnType === voidType || targetReturnType === anyType) { - return result; - } - const sourceReturnType = isResolvingReturnTypeOfSignature(source) ? anyType - : source.declaration && isJSConstructor(source.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(source.declaration.symbol)) - : getReturnTypeOfSignature(source); - // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions const targetTypePredicate = getTypePredicateOfSignature(target); if (targetTypePredicate) { @@ -20905,6 +21053,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } else { + const targetReturnType = target.declaration && isJSConstructor(target.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(target.declaration.symbol)) + : getReturnTypeOfSignature(target); + if (targetReturnType === voidType || targetReturnType === anyType) { + return result; + } + const sourceReturnType = source.declaration && isJSConstructor(source.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(source.declaration.symbol)) + : getReturnTypeOfSignature(source); // When relating callback signatures, we still need to relate return types bi-variantly as otherwise // the containing type wouldn't be co-variant. For example, interface Foo { add(cb: () => T): void } // wouldn't be co-variant for T without this rule. @@ -32071,19 +32226,19 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const propName = isJsxNamespacedName(node.tagName) ? getEscapedTextOfJsxNamespacedName(node.tagName) : node.tagName.escapedText; const intrinsicProp = getPropertyOfType(intrinsicElementsType, propName); if (intrinsicProp) { - links.jsxFlags |= JsxFlags.IntrinsicNamedElement; + links.jsxFlags! |= JsxFlags.IntrinsicNamedElement; return links.resolvedSymbol = intrinsicProp; } // Intrinsic string indexer case const indexSymbol = getApplicableIndexSymbol(intrinsicElementsType, getStringLiteralType(unescapeLeadingUnderscores(propName))); if (indexSymbol) { - links.jsxFlags |= JsxFlags.IntrinsicIndexedElement; + links.jsxFlags! |= JsxFlags.IntrinsicIndexedElement; return links.resolvedSymbol = indexSymbol; } if (getTypeOfPropertyOrIndexSignatureOfType(intrinsicElementsType, propName)) { - links.jsxFlags |= JsxFlags.IntrinsicIndexedElement; + links.jsxFlags! |= JsxFlags.IntrinsicIndexedElement; return links.resolvedSymbol = intrinsicElementsType.symbol; } @@ -32306,10 +32461,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const links = getNodeLinks(node); if (!links.resolvedJsxElementAttributesType) { const symbol = getIntrinsicTagSymbol(node); - if (links.jsxFlags & JsxFlags.IntrinsicNamedElement) { + if (links.jsxFlags! & JsxFlags.IntrinsicNamedElement) { return links.resolvedJsxElementAttributesType = getTypeOfSymbol(symbol) || errorType; } - else if (links.jsxFlags & JsxFlags.IntrinsicIndexedElement) { + else if (links.jsxFlags! & JsxFlags.IntrinsicIndexedElement) { const propName = isJsxNamespacedName(node.tagName) ? getEscapedTextOfJsxNamespacedName(node.tagName) : node.tagName.escapedText; return links.resolvedJsxElementAttributesType = getApplicableIndexInfoForName(getJsxType(JsxNames.IntrinsicElements, node), propName)?.type || errorType; } @@ -33912,7 +34067,24 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { thisArgumentType; } + function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: readonly Expression[], checkMode: CheckMode, context: InferenceContext): Type[] { + let result: Type[]; + speculate(() => { + // We speculate here so we can preemptively "lock in" this signature as the resolved signature for the node, + // and set its' resolved return type to `any`, since anywhere we witness it in the arguments is a circular reference, which must not contribute to assignability + // of the inferred arguments. + getNodeLinks(node).resolvedSignature = signature; // Usually this would be the instantiated signature, post-inference. Here, we toss in the uninstantiated signature while we speculate. + const resolvedReturn = signature.resolvedReturnType; // this is likely `undefined` unless already pre-cached + signature.resolvedReturnType = resolvedReturn || anyType; // flag circularity locations as `any` - they will not contribute to the validity of the call + result = inferTypeArgumentsWorker(node, signature, args, checkMode, context); + signature.resolvedReturnType = resolvedReturn; + return false; // always reset checker state, so the cached signature (and any follow-on caching) are undone + }); + return result!; + } + + function inferTypeArgumentsWorker(node: CallLikeExpression, signature: Signature, args: readonly Expression[], checkMode: CheckMode, context: InferenceContext): Type[] { if (isJsxOpeningLikeElement(node)) { return inferJsxTypeArguments(node, signature, checkMode, context); } @@ -48814,6 +48986,136 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return getDeclarationOfKind(moduleSymbol, SyntaxKind.SourceFile); } + /** + * @param cb Speculation callback, operations performed within this context will be rewound and uncached unless the helper returns a truthy value + */ + function speculate(cb: () => T): T | undefined { + const initialState = snapshotCheckerState(); + const result = cb(); + if (!result) { + restoreCheckerState(initialState); + return undefined; + } + return result; + } + + function registerSpeculativeCache(collection: T): T { + speculativeCaches.push(collection); + return collection; + } + + type SavedCheckerState = { restores: (() => void)[], transientSymbols: typeof transientSymbols }; + + function snapshotCheckerState(): SavedCheckerState { + const state: SavedCheckerState = { restores: concatenate(map(speculativeCaches, save), mapDefined(transientSymbols, saveTransientSymbolLink)), transientSymbols }; + transientSymbols = []; + return state; + + function saveTransientSymbolLink(ref: WeakRef): (() => void) | undefined { + const res = ref.deref(); + if (res) { + return save(res.links); + } + } + + // TODO: Override error reporting functions to just defer work until speculation + // helper is confirmed as locked-in, to avoid the work of building diagnostics until + // we know we're actually going to use them. + + function save(cache: (typeof speculativeCaches)[number] | TransientSymbolLinks): () => void { + if (Array.isArray(cache)) { + for (const k in cache) { + const v = cache[k]; + if (v instanceof NodeLinks || v instanceof SymbolLinks) { + return saveLinksArray(cache); + } + break; + } + // A totally empty links array may get `save`'d as a normal array. That should be fine - we should reset it to empty. + return saveArray(cache); + } + else if (cache instanceof Map) { + return saveMap(cache); + } + else if (cache instanceof Set) { + return saveSet(cache); + } + else if (cache instanceof SymbolLinks) { + return saveLinks(cache); + } + else if (cache.add! && cache.getDiagnostics!) { + return saveDiagnosticCollection(cache); + } + return Debug.fail("Unknown speculative cache type"); + } + + function saveLinks(cache: SymbolLinks) { + const saved = cache.save(); + return () => cache.restore(saved); + } + + function saveLinksArray(cache: NodeLinks[] | SymbolLinks[]) { + const og: SaveableLinks[] = []; + for (const k in cache) { + og[k] = cache[k].save(); + } + return () => { + for (const k in cache) { + if (!og[k]) { + delete cache[k]; + } + else { + cache[k].restore(og[k]); + } + } + } + } + + // TODO: All these save/restore methods are as naive as you can get right now, which means speculation + // is insanely expensive, as it eagerly saving off the checker state + function saveArray(cache: unknown[]) { + const original = cache.slice(); + return () => { + cache.length = 0; + cache.push(...original); + }; + } + + function saveMap(cache: Map) { + const original = arrayFrom(cache.entries()) + return () => { + cache.clear() + for (const [k, v] of original) { + cache.set(k, v); + } + }; + } + + function saveSet(cache: Set) { + const original = arrayFrom(cache.entries()); + return () => { + cache.clear(); + for (const [_, v] of original) { + cache.add(v); + } + }; + } + + function saveDiagnosticCollection(cache: DiagnosticCollection) { + const c = cache.checkpoint(); + return () => { + cache.revert(c); + } + } + } + + function restoreCheckerState(state: SavedCheckerState) { + for (const restore of state.restores) { + restore(); + } + transientSymbols = state.transientSymbols; // simply discard the current array - all those transient symbols should fall out of scope. + } + function initializeTypeChecker() { // Bind all source files and propagate errors for (const file of host.getSourceFiles()) { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 422195ae6992b..fc2a2a99f34d0 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5,7 +5,6 @@ import { GetCanonicalFileName, MapLike, ModeAwareCache, - ModeAwareCacheKey, ModuleResolutionCache, MultiMap, NodeFactoryFlags, @@ -15,6 +14,7 @@ import { Pattern, ProgramBuildInfo, SymlinkCache, + TransientSymbol, ThisContainer, } from "./_namespaces/ts"; @@ -5829,65 +5829,6 @@ export interface Symbol { /** @internal */ assignmentDeclarationMembers?: Map; // detected late-bound assignment declarations associated with the symbol } -// dprint-ignore -/** @internal */ -export interface SymbolLinks { - _symbolLinksBrand: any; - immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead. - aliasTarget?: Symbol, // Resolved (non-alias) target of an alias - target?: Symbol; // Original version of an instantiated symbol - type?: Type; // Type of value symbol - writeType?: Type; // Type of value symbol in write contexts - nameType?: Type; // Type associated with a late-bound symbol - 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) - 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 - aliasTypeArguments?: readonly Type[] // Alias type arguments (if any) - inferredClassSymbol?: Map; // Symbol of an inferred ES5 constructor function - mapper?: TypeMapper; // Type mapper for instantiation alias - referenced?: boolean; // True if alias symbol has been referenced as a value that can be emitted - constEnumReferenced?: boolean; // True if alias symbol resolves to a const enum and is referenced as a value ('referenced' will be false) - containingType?: UnionOrIntersectionType; // Containing union or intersection type for synthetic property - leftSpread?: Symbol; // Left source for synthetic spread property - rightSpread?: Symbol; // Right source for synthetic spread property - syntheticOrigin?: Symbol; // For a property on a mapped or spread type, points back to the original property - isDiscriminantProperty?: boolean; // True if discriminant synthetic property - resolvedExports?: SymbolTable; // Resolved exports of module or combined early- and late-bound static members of a class. - resolvedMembers?: SymbolTable; // Combined early- and late-bound members of a symbol - exportsChecked?: boolean; // True if exports of external module have been checked - typeParametersChecked?: boolean; // True if type parameters of merged class and interface declarations have been checked. - isDeclarationWithCollidingName?: boolean; // True if symbol is block scoped redeclaration - bindingElement?: BindingElement; // Binding element associated with property symbol - exportsSomeValue?: boolean; // True if module exports some value (not just types) - enumKind?: EnumKind; // Enum declaration classification - originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol` - lateSymbol?: Symbol; // Late-bound symbol for a computed property - specifierCache?: Map; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings - extendedContainers?: Symbol[]; // Containers (other than the parent) which this symbol is aliased in - extendedContainersByFile?: Map; // Containers (other than the parent) which this symbol is aliased in - variances?: VarianceFlags[]; // Alias symbol type argument variance cache - deferralConstituents?: Type[]; // Calculated list of constituents for a deferred type - deferralWriteConstituents?: Type[]; // Constituents of a deferred `writeType` - deferralParent?: Type; // Source union/intersection of a deferred type - cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target - typeOnlyDeclaration?: TypeOnlyAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs - typeOnlyExportStarMap?: Map<__String, ExportDeclaration & { readonly isTypeOnly: true, readonly moduleSpecifier: Expression }>; // Set on a module symbol when some of its exports were resolved through a 'export type * from "mod"' declaration - typeOnlyExportStarName?: __String; // Set to the name of the symbol re-exported by an 'export type *' declaration, when different from the symbol name - isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor - tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label - accessibleChainCache?: Map; - filteredIndexSymbolCache?: Map //Symbol with applicable declarations -} - -/** @internal */ -export const enum EnumKind { - Numeric, // Numeric enum (each member has a TypeFlags.Enum type) - Literal, // Literal enum (each member has a TypeFlags.EnumLiteral type) -} - // dprint-ignore /** @internal */ export const enum CheckFlags { @@ -5918,39 +5859,6 @@ export const enum CheckFlags { Partial = ReadPartial | WritePartial, } -/** @internal */ -export interface TransientSymbolLinks extends SymbolLinks { - checkFlags: CheckFlags; -} - -/** @internal */ -export interface TransientSymbol extends Symbol { - links: TransientSymbolLinks; -} - -/** @internal */ -export interface MappedSymbolLinks extends TransientSymbolLinks { - mappedType: MappedType; - keyType: Type; -} - -/** @internal */ -export interface MappedSymbol extends TransientSymbol { - links: MappedSymbolLinks; -} - -/** @internal */ -export interface ReverseMappedSymbolLinks extends TransientSymbolLinks { - propertyType: Type; - mappedType: MappedType; - constraintType: IndexType; -} - -/** @internal */ -export interface ReverseMappedSymbol extends TransientSymbol { - links: ReverseMappedSymbolLinks; -} - export const enum InternalSymbolName { Call = "__call", // Call signatures Constructor = "__constructor", // Constructor implementations @@ -6031,52 +5939,6 @@ export const enum NodeCheckFlags { InCheckIdentifier = 1 << 22, } -// dprint-ignore -/** @internal */ -export interface NodeLinks { - flags: NodeCheckFlags; // Set of flags specific to Node - resolvedType?: Type; // Cached type of type node - resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag - resolvedSignature?: Signature; // Cached signature of signature node or call expression - resolvedSymbol?: Symbol; // Cached name resolution result - resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result - effectsSignature?: Signature; // Signature with possible control flow effects - enumMemberValue?: string | number; // Constant value of enum member - isVisible?: boolean; // Is this node visible - containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference - hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context - jsxFlags: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with - resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element - resolvedJsxElementAllAttributesType?: Type; // resolved all element attributes type of a JSX openinglike element - resolvedJSDocType?: Type; // Resolved type of a JSDoc type reference - switchTypes?: Type[]; // Cached array of switch case expression types - jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node - jsxImplicitImportContainer?: Symbol | false; // Resolved module symbol the implicit jsx import of this file should refer to - contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive - deferredNodes?: Set; // Set of nodes whose checking has been deferred - capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement - outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type - isExhaustive?: boolean | 0; // Is node an exhaustive switch statement (0 indicates in-process resolution) - skipDirectInference?: true; // Flag set by the API `getContextualType` call on a node when `Completions` is passed to force the checker to skip making inferences to a node's type - declarationRequiresScopeChange?: boolean; // Set by `useOuterVariableScopeInParameter` in checker when downlevel emit would change the name resolution scope inside of a parameter. - serializedTypes?: Map; // Collection of types serialized at this location - decoratorSignature?: Signature; // Signature for decorator as if invoked by the runtime. - spreadIndices?: { first: number | undefined, last: number | undefined }; // Indices of first and last spread elements in array literal - parameterInitializerContainsUndefined?: boolean; // True if this is a parameter declaration whose type annotation contains "undefined". - fakeScopeForSignatureDeclaration?: "params" | "typeParams"; // If present, this is a fake scope injected into an enclosing declaration chain. - assertionExpressionType?: Type; // Cached type of the expression of a type assertion -} - -/** @internal */ -export type TrackedSymbol = [symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags]; -/** @internal */ -export interface SerializedTypeEntry { - node: TypeNode; - truncating?: boolean; - addedLength: number; - trackedSymbols: readonly TrackedSymbol[] | undefined; -} - // dprint-ignore export const enum TypeFlags { Any = 1 << 0, @@ -9768,6 +9630,14 @@ export interface DiagnosticCollection { // Otherwise, returns all the diagnostics (global and file associated) in this collection. getDiagnostics(): Diagnostic[]; getDiagnostics(fileName: string): DiagnosticWithLocation[]; + + checkpoint(): DiagnosticCollectionCheckpoint; + revert(position: DiagnosticCollectionCheckpoint): void; +} + +/** @internal */ +export interface DiagnosticCollectionCheckpoint { + __privateState: void; // Internal state saved is private to the collection implementation } // SyntaxKind.SyntaxList diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index f2acc826efafd..8074346cf332c 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -94,6 +94,7 @@ import { Diagnostic, DiagnosticArguments, DiagnosticCollection, + DiagnosticCollectionCheckpoint, DiagnosticMessage, DiagnosticMessageChain, DiagnosticRelatedInformation, @@ -5771,11 +5772,19 @@ export function getSemanticJsxChildren(children: readonly JsxChild[]) { }); } +interface DiagnosticCollectionCheckpointInternals { + __privateState?: void; + nonFileDiagnostics: SortedArray; + filesWithDiagnostics: SortedArray; + fileDiagnostics: Map>; + hasReadNonFileDiagnostics: boolean; +} + /** @internal */ export function createDiagnosticCollection(): DiagnosticCollection { let nonFileDiagnostics = [] as Diagnostic[] as SortedArray; // See GH#19873 - const filesWithDiagnostics = [] as string[] as SortedArray; - const fileDiagnostics = new Map>(); + let filesWithDiagnostics = [] as string[] as SortedArray; + let fileDiagnostics = new Map>(); let hasReadNonFileDiagnostics = false; return { @@ -5783,8 +5792,31 @@ export function createDiagnosticCollection(): DiagnosticCollection { lookup, getGlobalDiagnostics, getDiagnostics, + checkpoint, + revert }; + // TODO: Copying the state at time of checkpoint is slow to checkpoint and memory intensive (but fast to restore) + // - recording deltas on `add` after a checkpoint would be much better + function checkpoint(): DiagnosticCollectionCheckpoint { + const c: DiagnosticCollectionCheckpointInternals = { + nonFileDiagnostics: nonFileDiagnostics.slice() as SortedArray, + filesWithDiagnostics: filesWithDiagnostics.slice() as SortedArray, + fileDiagnostics: new Map(map(arrayFrom(fileDiagnostics.entries()), ([k, v]) => [k, v.slice() as SortedArray] as const)), + hasReadNonFileDiagnostics + }; + return c as DiagnosticCollectionCheckpoint; + } + + function revert(checkpoint: DiagnosticCollectionCheckpoint) { + ({ + nonFileDiagnostics, + filesWithDiagnostics, + fileDiagnostics, + hasReadNonFileDiagnostics, + } = checkpoint as DiagnosticCollectionCheckpointInternals); + } + function lookup(diagnostic: Diagnostic): Diagnostic | undefined { let diagnostics: SortedArray | undefined; if (diagnostic.file) { diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index 3b772f7d33f0f..0691623813570 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -4,8 +4,8 @@ "outDir": "../built/local", "pretty": true, - "lib": ["es2020"], - "target": "es2020", + "lib": ["es2021"], + "target": "es2021", "module": "CommonJS", "moduleResolution": "node", diff --git a/tests/cases/compiler/noCircularityErrorDeferredTypeReferenceSignatureCycle.ts b/tests/cases/compiler/noCircularityErrorDeferredTypeReferenceSignatureCycle.ts new file mode 100644 index 0000000000000..e34b910d2e59b --- /dev/null +++ b/tests/cases/compiler/noCircularityErrorDeferredTypeReferenceSignatureCycle.ts @@ -0,0 +1,14 @@ +// @strict: true +type TypeReference = () => TreeSchema; + +class TreeSchema { + public constructor(public readonly info: T) {} +} + +function map(types: T): TreeSchema { + return new TreeSchema(types); +} + +const jsonRoot = () => jsonObject; + +const jsonObject = map(jsonRoot); \ No newline at end of file From c507e37e7ea887c7c1aa3696220cd26a0d07509f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Wed, 14 Feb 2024 14:26:26 -0800 Subject: [PATCH 02/18] Still a bit WIP, but most failing tests look like improvements now --- src/compiler/checker.ts | 290 ++++++++++-------- src/compiler/types.ts | 2 +- ...rrorDeferredTypeReferenceSignatureCycle.ts | 14 - 3 files changed, 166 insertions(+), 140 deletions(-) delete mode 100644 tests/cases/compiler/noCircularityErrorDeferredTypeReferenceSignatureCycle.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a97875e197979..98b74f5d61104 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -874,6 +874,7 @@ import { NodeWithTypeArguments, NonNullChain, NonNullExpression, + noop, not, noTruncationMaximumTruncationLength, NumberLiteralType, @@ -1373,24 +1374,40 @@ const intrinsicTypeKinds: ReadonlyMap = new Map(Objec NoInfer: IntrinsicTypeKind.NoInfer, })); -class SaveableLinks { - save() { +/** @internal */ +export class SaveableLinks { + /** + * Static list of fields which should be reset when state is rewound - + * meaning their data is not cached across speculation boundaries. + * + * TODO: This would be better tracked with decorators. + */ + static speculativeCaches = new Set(); + declare ["constructor"]: typeof SaveableLinks; + save(): Partial { // TODO: Optimize perf to delay copies until necessary, and to copy only changes. // TODO: Some nested deep caches like `specifierCache` or more meaningfully - // `extendedContainersByFile` should really be deep copied/restored, since they may refernce + // `extendedContainersByFile` should really be deep copied/restored, since they may reference // Symbol information for discarded speculative symbols. - // TODO: The return type is a `SaveableLinks`, which is an abuse of a type system bug - - // the spread will peel away the prototype - there won't be `.save` or `.restore` methods on it. - return { ...this }; + // TODO: The return type is a `this`, which is an abuse of the type system + const res = {} as Partial; + for (const k of this.constructor.speculativeCaches) { + res[k as keyof this] = this[k as keyof this]; + } + return res; } - restore(state: T) { - for (const k in state) { - if (Object.prototype.hasOwnProperty.call(state, k)) { - this[k as keyof this] = state[k] as unknown as this[keyof this]; + restore>(state: T | undefined) { + if (state) { + for (const k in state) { + if (!this.constructor.speculativeCaches.has(k)) continue; + if (Object.prototype.hasOwnProperty.call(state, k)) { + this[k as keyof this] = state[k] as unknown as this[keyof this]; + } } } for (const k in this) { - if (!Object.prototype.hasOwnProperty.call(state, k)) { + if (!this.constructor.speculativeCaches.has(k)) continue; + if (!state || !Object.prototype.hasOwnProperty.call(state, k)) { // TODO: `delete` has perf implications, but we really do want to *remove* the keys we added // Still, `= undefined` might make future copies unnecessarily heavier, but should otherwise be fine. // Should choose between them based on perf testing. @@ -1401,14 +1418,14 @@ class SaveableLinks { } /** @internal */ -const enum EnumKind { +export const enum EnumKind { Numeric, // Numeric enum (each member has a TypeFlags.Enum type) Literal, // Literal enum (each member has a TypeFlags.EnumLiteral type) } // dprint-ignore /** @internal */ -class SymbolLinks extends SaveableLinks { +export class SymbolLinks extends SaveableLinks { declare _symbolLinksBrand: any; declare immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead. declare aliasTarget?: Symbol; // Resolved (non-alias) target of an alias @@ -1457,40 +1474,48 @@ class SymbolLinks extends SaveableLinks { declare tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label declare accessibleChainCache?: Map; declare filteredIndexSymbolCache?: Map //Symbol with applicable declarations -}; -/** @internal */ -interface TransientSymbolLinks extends SymbolLinks { + static override speculativeCaches = new Set([ "type", "writeType", "nameType" ]); +} + +/** @internal */ +export interface TransientSymbolLinks extends SymbolLinks { checkFlags: CheckFlags; } -/** @internal */ +/** @internal */ export interface TransientSymbol extends Symbol { links: TransientSymbolLinks; } -interface MappedSymbolLinks extends TransientSymbolLinks { +/** @internal */ +export interface MappedSymbolLinks extends TransientSymbolLinks { mappedType: MappedType; keyType: Type; } -interface MappedSymbol extends TransientSymbol { +/** @internal */ +export interface MappedSymbol extends TransientSymbol { links: MappedSymbolLinks; } -interface ReverseMappedSymbolLinks extends TransientSymbolLinks { +/** @internal */ +export interface ReverseMappedSymbolLinks extends TransientSymbolLinks { propertyType: Type; mappedType: MappedType; constraintType: IndexType; } -interface ReverseMappedSymbol extends TransientSymbol { +/** @internal */ +export interface ReverseMappedSymbol extends TransientSymbol { links: ReverseMappedSymbolLinks; } -type TrackedSymbol = [symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags]; +/** @internal */ +export type TrackedSymbol = [symbol: Symbol, enclosingDeclaration: Node | undefined, meaning: SymbolFlags]; -interface SerializedTypeEntry { +/** @internal */ +export interface SerializedTypeEntry { node: TypeNode; truncating?: boolean; addedLength: number; @@ -1498,7 +1523,8 @@ interface SerializedTypeEntry { } // dprint-ignore -class NodeLinks extends SaveableLinks { +/** @internal */ +export class NodeLinks extends SaveableLinks { declare flags: NodeCheckFlags; // Set of flags specific to Node declare resolvedType?: Type; // Cached type of type node declare resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag @@ -1534,7 +1560,20 @@ class NodeLinks extends SaveableLinks { super(); this.flags = NodeCheckFlags.None; } -}; + + static override speculativeCaches = new Set([ + "flags", + "resolvedType", + "resolvedEnumType", + "resolvedSignature", + "resolvedSymbol", + "resolvedIndexInfo", + "effectsSignature", + "switchTypes", + "contextFreeType", + "assertionExpressionType", + ]); +} /** @internal */ export function getNodeId(node: Node): number { @@ -1564,6 +1603,10 @@ export function isInstantiatedModule(node: ModuleDeclaration, preserveConstEnums /** @internal */ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { + // Why var? It avoids TDZ checks in the runtime which can be costly. + // See: https://github.com/microsoft/TypeScript/issues/52924 + /* eslint-disable no-var */ + // List of all caches whose state should be saved and potentially restored on completion of a speculative typechecking operation var speculativeCaches: (any[] | Map | Set | DiagnosticCollection)[] = []; // Transient symbols store their links directly on them, so each transient symbol is also a small speculative cache. @@ -1572,9 +1615,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // This has to be an array of weak refs and not a weak map or weak set because we need to iterate over them to attempt to save their state. var transientSymbols: WeakRef[] = []; - // Why var? It avoids TDZ checks in the runtime which can be costly. - // See: https://github.com/microsoft/TypeScript/issues/52924 - /* eslint-disable no-var */ var deferredDiagnosticsCallbacks: (() => void)[] = registerSpeculativeCache([]); var addLazyDiagnostic = (arg: () => void) => { @@ -2095,29 +2135,29 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return res; } - var tupleTypes = registerSpeculativeCache(new Map()); - var unionTypes = registerSpeculativeCache(new Map()); - var unionOfUnionTypes = registerSpeculativeCache(new Map()); - var intersectionTypes = registerSpeculativeCache(new Map()); - var stringLiteralTypes = registerSpeculativeCache(new Map()); - var numberLiteralTypes = registerSpeculativeCache(new Map()); - var bigIntLiteralTypes = registerSpeculativeCache(new Map()); - var enumLiteralTypes = registerSpeculativeCache(new Map()); - var indexedAccessTypes = registerSpeculativeCache(new Map()); - var templateLiteralTypes = registerSpeculativeCache(new Map()); - var stringMappingTypes = registerSpeculativeCache(new Map()); - var substitutionTypes = registerSpeculativeCache(new Map()); - var subtypeReductionCache = registerSpeculativeCache(new Map()); - var decoratorContextOverrideTypeCache = registerSpeculativeCache(new Map()); - var cachedTypes = registerSpeculativeCache(new Map()); - var evolvingArrayTypes: EvolvingArrayType[] = registerSpeculativeCache([]); - var undefinedProperties: SymbolTable = registerSpeculativeCache(new Map()); - var markerTypes = registerSpeculativeCache(new Set()); + var tupleTypes = new Map(); + var unionTypes = new Map(); + var unionOfUnionTypes = new Map(); + var intersectionTypes = new Map(); + var stringLiteralTypes = new Map(); + var numberLiteralTypes = new Map(); + var bigIntLiteralTypes = new Map(); + var enumLiteralTypes = new Map(); + var indexedAccessTypes = new Map(); + var templateLiteralTypes = new Map(); + var stringMappingTypes = new Map(); + var substitutionTypes = new Map(); + var subtypeReductionCache = new Map(); + var decoratorContextOverrideTypeCache = new Map(); + var cachedTypes = new Map(); + var evolvingArrayTypes: EvolvingArrayType[] = []; + var undefinedProperties: SymbolTable = new Map(); + var markerTypes = new Set(); var unknownSymbol = createSymbol(SymbolFlags.Property, "unknown" as __String); var resolvingSymbol = createSymbol(0, InternalSymbolName.Resolving); - var unresolvedSymbols = registerSpeculativeCache(new Map()); - var errorTypes = registerSpeculativeCache(new Map()); + var unresolvedSymbols = new Map(); + var errorTypes = new Map(); // We specifically create the `undefined` and `null` types before any other types that can occur in // unions such that they are given low type IDs and occur first in the sorted list of union constituents. @@ -2418,6 +2458,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var _jsxNamespace: __String; var _jsxFactoryEntity: EntityName | undefined; + // Relationship caches need to be speculative so we can un-upgrade "ErrorAndReported" results back down, since we're rewinding the error + // Otherwise, we think we've emitted lots of elaboration that we just swallow up in discarded speculative contexts var subtypeRelation = registerSpeculativeCache(new Map()); var strictSubtypeRelation = registerSpeculativeCache(new Map()); var assignableRelation = registerSpeculativeCache(new Map()); @@ -34067,24 +34109,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { thisArgumentType; } - function inferTypeArguments(node: CallLikeExpression, signature: Signature, args: readonly Expression[], checkMode: CheckMode, context: InferenceContext): Type[] { - let result: Type[]; - speculate(() => { - // We speculate here so we can preemptively "lock in" this signature as the resolved signature for the node, - // and set its' resolved return type to `any`, since anywhere we witness it in the arguments is a circular reference, which must not contribute to assignability - // of the inferred arguments. - getNodeLinks(node).resolvedSignature = signature; // Usually this would be the instantiated signature, post-inference. Here, we toss in the uninstantiated signature while we speculate. - const resolvedReturn = signature.resolvedReturnType; // this is likely `undefined` unless already pre-cached - signature.resolvedReturnType = resolvedReturn || anyType; // flag circularity locations as `any` - they will not contribute to the validity of the call - result = inferTypeArgumentsWorker(node, signature, args, checkMode, context); - signature.resolvedReturnType = resolvedReturn; - return false; // always reset checker state, so the cached signature (and any follow-on caching) are undone - }); - return result!; - } - - function inferTypeArgumentsWorker(node: CallLikeExpression, signature: Signature, args: readonly Expression[], checkMode: CheckMode, context: InferenceContext): Type[] { if (isJsxOpeningLikeElement(node)) { return inferJsxTypeArguments(node, signature, checkMode, context); } @@ -35020,63 +35045,67 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { continue; } + const result = speculate(() => { + let checkCandidate: Signature; + let inferenceContext: InferenceContext | undefined; - let checkCandidate: Signature; - let inferenceContext: InferenceContext | undefined; - - if (candidate.typeParameters) { - let typeArgumentTypes: Type[] | undefined; - if (some(typeArguments)) { - typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); - if (!typeArgumentTypes) { - candidateForTypeArgumentError = candidate; - continue; + if (candidate.typeParameters) { + let typeArgumentTypes: Type[] | undefined; + if (some(typeArguments)) { + typeArgumentTypes = checkTypeArguments(candidate, typeArguments, /*reportErrors*/ false); + if (!typeArgumentTypes) { + candidateForTypeArgumentError = candidate; + return false; + } } - } - else { - inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None); - typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext); - argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal; - } - checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters); - // If the original signature has a generic rest type, instantiation may produce a - // signature with different arity and we need to perform another arity check. - if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { - candidateForArgumentArityError = checkCandidate; - continue; - } - } - else { - checkCandidate = candidate; - } - if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { - // Give preference to error candidates that have no rest parameters (as they are more specific) - (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); - continue; - } - if (argCheckMode) { - // If one or more context sensitive arguments were excluded, we start including - // them now (and keeping do so for any subsequent candidates) and perform a second - // round of type inference and applicability checking for this particular candidate. - argCheckMode = CheckMode.Normal; - if (inferenceContext) { - const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext); - checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters); + else { + inferenceContext = createInferenceContext(candidate.typeParameters, candidate, /*flags*/ isInJSFile(node) ? InferenceFlags.AnyDefault : InferenceFlags.None); + typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode | CheckMode.SkipGenericFunctions, inferenceContext); + argCheckMode |= inferenceContext.flags & InferenceFlags.SkippedGenericFunction ? CheckMode.SkipGenericFunctions : CheckMode.Normal; + } + checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext && inferenceContext.inferredTypeParameters); // If the original signature has a generic rest type, instantiation may produce a // signature with different arity and we need to perform another arity check. if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { candidateForArgumentArityError = checkCandidate; - continue; + return false; } } + else { + checkCandidate = candidate; + } if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { // Give preference to error candidates that have no rest parameters (as they are more specific) (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); - continue; + return false; } + if (argCheckMode) { + // If one or more context sensitive arguments were excluded, we start including + // them now (and keeping do so for any subsequent candidates) and perform a second + // round of type inference and applicability checking for this particular candidate. + argCheckMode = CheckMode.Normal; + if (inferenceContext) { + const typeArgumentTypes = inferTypeArguments(node, candidate, args, argCheckMode, inferenceContext); + checkCandidate = getSignatureInstantiation(candidate, typeArgumentTypes, isInJSFile(candidate.declaration), inferenceContext.inferredTypeParameters); + // If the original signature has a generic rest type, instantiation may produce a + // signature with different arity and we need to perform another arity check. + if (getNonArrayRestType(candidate) && !hasCorrectArity(node, args, checkCandidate, signatureHelpTrailingComma)) { + candidateForArgumentArityError = checkCandidate; + return false; + } + } + if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { + // Give preference to error candidates that have no rest parameters (as they are more specific) + (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); + return false; + } + } + candidates[candidateIndex] = checkCandidate; + return checkCandidate; + }); + if (result) { + return result; } - candidates[candidateIndex] = checkCandidate; - return checkCandidate; } return undefined; @@ -44112,10 +44141,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isGeneratorMethod || isIteratorMethod) { const globalType = isGeneratorMethod ? globalGeneratorType : globalIteratorType; const { mapper } = methodType as AnonymousType; + const [ yieldType, returnType, nextType ] = globalType.typeParameters!; return createIterationTypes( - getMappedType(globalType.typeParameters![0], mapper!), - getMappedType(globalType.typeParameters![1], mapper!), - methodName === "next" ? getMappedType(globalType.typeParameters![2], mapper!) : undefined, + mapper ? getMappedType(yieldType, mapper) : yieldType, + mapper ? getMappedType(returnType, mapper) : returnType, + methodName === "next" ? mapper ? getMappedType(nextType, mapper) : nextType : undefined, ); } } @@ -48996,6 +49026,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { restoreCheckerState(initialState); return undefined; } + transientSymbols = concatenate(initialState.transientSymbols, transientSymbols); return result; } @@ -49004,7 +49035,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return collection; } - type SavedCheckerState = { restores: (() => void)[], transientSymbols: typeof transientSymbols }; + interface SavedCheckerState { + restores: (() => void)[]; + transientSymbols: typeof transientSymbols; + } function snapshotCheckerState(): SavedCheckerState { const state: SavedCheckerState = { restores: concatenate(map(speculativeCaches, save), mapDefined(transientSymbols, saveTransientSymbolLink)), transientSymbols }; @@ -49014,7 +49048,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function saveTransientSymbolLink(ref: WeakRef): (() => void) | undefined { const res = ref.deref(); if (res) { - return save(res.links); + return save(ref); } } @@ -49022,7 +49056,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // helper is confirmed as locked-in, to avoid the work of building diagnostics until // we know we're actually going to use them. - function save(cache: (typeof speculativeCaches)[number] | TransientSymbolLinks): () => void { + function save(cache: (typeof speculativeCaches)[number] | WeakRef): () => void { if (Array.isArray(cache)) { for (const k in cache) { const v = cache[k]; @@ -49040,39 +49074,45 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else if (cache instanceof Set) { return saveSet(cache); } - else if (cache instanceof SymbolLinks) { + else if (cache instanceof WeakRef) { return saveLinks(cache); } - else if (cache.add! && cache.getDiagnostics!) { + else if (cache.add! && cache.getDiagnostics!) { // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion return saveDiagnosticCollection(cache); } return Debug.fail("Unknown speculative cache type"); } - function saveLinks(cache: SymbolLinks) { - const saved = cache.save(); - return () => cache.restore(saved); + function saveLinks(cache: WeakRef) { + const saved = cache.deref()?.links.save(); + if (!saved) { + return noop; + } + return () => cache.deref()?.links.restore(saved); } function saveLinksArray(cache: NodeLinks[] | SymbolLinks[]) { - const og: SaveableLinks[] = []; + const og: Partial[] = []; for (const k in cache) { - og[k] = cache[k].save(); + if (cache[k]) { + og[k] = cache[k].save(); + } } return () => { for (const k in cache) { if (!og[k]) { - delete cache[k]; + // TODO: there has to be a way to phase the types/cast to make these directly callable + cache[k].restore.call(cache[k], undefined); } else { - cache[k].restore(og[k]); + cache[k].restore.call(cache[k], og[k]); } } } } // TODO: All these save/restore methods are as naive as you can get right now, which means speculation - // is insanely expensive, as it eagerly saving off the checker state + // is insanely expensive, as it is eagerly saving off the checker state function saveArray(cache: unknown[]) { const original = cache.slice(); return () => { diff --git a/src/compiler/types.ts b/src/compiler/types.ts index fc2a2a99f34d0..40271a6e54354 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -14,8 +14,8 @@ import { Pattern, ProgramBuildInfo, SymlinkCache, - TransientSymbol, ThisContainer, + TransientSymbol, } from "./_namespaces/ts"; // branded string type used to store absolute, normalized and canonicalized paths diff --git a/tests/cases/compiler/noCircularityErrorDeferredTypeReferenceSignatureCycle.ts b/tests/cases/compiler/noCircularityErrorDeferredTypeReferenceSignatureCycle.ts deleted file mode 100644 index e34b910d2e59b..0000000000000 --- a/tests/cases/compiler/noCircularityErrorDeferredTypeReferenceSignatureCycle.ts +++ /dev/null @@ -1,14 +0,0 @@ -// @strict: true -type TypeReference = () => TreeSchema; - -class TreeSchema { - public constructor(public readonly info: T) {} -} - -function map(types: T): TreeSchema { - return new TreeSchema(types); -} - -const jsonRoot = () => jsonObject; - -const jsonObject = map(jsonRoot); \ No newline at end of file From eaa6845bb30c7be70b621d167e6edbd59e607aa7 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 15 Feb 2024 11:56:09 -0800 Subject: [PATCH 03/18] These all seem like logical outcomes to the changes added --- .../contextualTypingOfTooShortOverloads.types | 14 +- .../reference/destructuringTuple.errors.txt | 35 +- .../reference/destructuringTuple.symbols | 2 - .../reference/destructuringTuple.types | 14 +- .../fixingTypeParametersRepeatedly1.types | 2 +- ...fixingTypeParametersRepeatedly2.errors.txt | 17 +- .../fixingTypeParametersRepeatedly2.types | 2 +- .../fixingTypeParametersRepeatedly3.types | 4 +- ...torFixesInferencesAppropriately.errors.txt | 34 + ...ructorFixesInferencesAppropriately.symbols | 2 - ...structorFixesInferencesAppropriately.types | 16 +- ...nWithConstraintCheckingDeferred.errors.txt | 99 +-- ...lutionWithConstraintCheckingDeferred.types | 32 +- .../overloadsWithProvisionalErrors.errors.txt | 8 +- .../overloadsWithProvisionalErrors.types | 8 +- .../parenthesizedContexualTyping1.types | 106 ++-- .../ramdaToolsNoInfinite2.errors.txt | 581 ++++++++++++++++++ ...romGeneratorMakesRequiredParams.errors.txt | 2 - .../baselines/reference/targetTypeArgs.types | 8 +- ...OnMethodReturnOfGenericInstance.errors.txt | 24 + ...ionalOnMethodReturnOfGenericInstance.types | 8 +- .../reference/unionOfClassCalls.types | 4 +- 22 files changed, 786 insertions(+), 236 deletions(-) create mode 100644 tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.errors.txt create mode 100644 tests/baselines/reference/ramdaToolsNoInfinite2.errors.txt create mode 100644 tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.errors.txt diff --git a/tests/baselines/reference/contextualTypingOfTooShortOverloads.types b/tests/baselines/reference/contextualTypingOfTooShortOverloads.types index b1e7e22b83bcc..b45aba8660af0 100644 --- a/tests/baselines/reference/contextualTypingOfTooShortOverloads.types +++ b/tests/baselines/reference/contextualTypingOfTooShortOverloads.types @@ -8,9 +8,9 @@ var use: Overload; use((req, res) => {}); >use((req, res) => {}) : void >use : Overload ->(req, res) => {} : (req: any, res: any) => void ->req : any ->res : any +>(req, res) => {} : (req: number, res: number) => void +>req : number +>res : number interface Overload { (handler1: (req1: string) => void): void; @@ -31,11 +31,11 @@ app.use((err: any, req, res, next) => { return; }); >app.use : IRouterHandler & IRouterMatcher >app : MyApp >use : IRouterHandler & IRouterMatcher ->(err: any, req, res, next) => { return; } : (err: any, req: any, res: any, next: any) => void +>(err: any, req, res, next) => { return; } : (err: any, req: Request, res: Response, next: NextFunction) => void >err : any ->req : any ->res : any ->next : any +>req : Request +>res : Response +>next : NextFunction interface MyApp { diff --git a/tests/baselines/reference/destructuringTuple.errors.txt b/tests/baselines/reference/destructuringTuple.errors.txt index 53bc232e331cd..37458392b906d 100644 --- a/tests/baselines/reference/destructuringTuple.errors.txt +++ b/tests/baselines/reference/destructuringTuple.errors.txt @@ -1,18 +1,8 @@ -destructuringTuple.ts(11,7): error TS2461: Type 'number' is not an array type. -destructuringTuple.ts(11,48): error TS2769: No overload matches this call. - Overload 1 of 3, '(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number', gave the following error. - Type 'never[]' is not assignable to type 'number'. - Overload 2 of 3, '(callbackfn: (previousValue: [], currentValue: number, currentIndex: number, array: number[]) => [], initialValue: []): []', gave the following error. - Type 'never[]' is not assignable to type '[]'. - Target allows only 0 element(s) but source may have more. -destructuringTuple.ts(11,60): error TS2769: No overload matches this call. - Overload 1 of 2, '(...items: ConcatArray[]): never[]', gave the following error. - Argument of type 'number' is not assignable to parameter of type 'ConcatArray'. - Overload 2 of 2, '(...items: ConcatArray[]): never[]', gave the following error. - Argument of type 'number' is not assignable to parameter of type 'ConcatArray'. +destructuringTuple.ts(11,7): error TS2461: Type 'unknown' is not an array type. +destructuringTuple.ts(11,48): error TS18046: 'accu' is of type 'unknown'. -==== destructuringTuple.ts (3 errors) ==== +==== destructuringTuple.ts (2 errors) ==== declare var tuple: [boolean, number, ...string[]]; const [a, b, c, ...rest] = tuple; @@ -25,22 +15,9 @@ destructuringTuple.ts(11,60): error TS2769: No overload matches this call. const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); ~~~~~~~ -!!! error TS2461: Type 'number' is not an array type. - ~~~~~~~~~~~~~~~ -!!! error TS2769: No overload matches this call. -!!! error TS2769: Overload 1 of 3, '(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number', gave the following error. -!!! error TS2769: Type 'never[]' is not assignable to type 'number'. -!!! error TS2769: Overload 2 of 3, '(callbackfn: (previousValue: [], currentValue: number, currentIndex: number, array: number[]) => [], initialValue: []): []', gave the following error. -!!! error TS2769: Type 'never[]' is not assignable to type '[]'. -!!! error TS2769: Target allows only 0 element(s) but source may have more. -!!! related TS6502 lib.es5.d.ts:--:--: The expected type comes from the return type of this signature. -!!! related TS6502 lib.es5.d.ts:--:--: The expected type comes from the return type of this signature. - ~~ -!!! error TS2769: No overload matches this call. -!!! error TS2769: Overload 1 of 2, '(...items: ConcatArray[]): never[]', gave the following error. -!!! error TS2769: Argument of type 'number' is not assignable to parameter of type 'ConcatArray'. -!!! error TS2769: Overload 2 of 2, '(...items: ConcatArray[]): never[]', gave the following error. -!!! error TS2769: Argument of type 'number' is not assignable to parameter of type 'ConcatArray'. +!!! error TS2461: Type 'unknown' is not an array type. + ~~~~ +!!! error TS18046: 'accu' is of type 'unknown'. const [oops2] = [1, 2, 3].reduce((acc: number[], e) => acc.concat(e), []); \ No newline at end of file diff --git a/tests/baselines/reference/destructuringTuple.symbols b/tests/baselines/reference/destructuringTuple.symbols index 9acc4ed15abed..45cd552e30de8 100644 --- a/tests/baselines/reference/destructuringTuple.symbols +++ b/tests/baselines/reference/destructuringTuple.symbols @@ -27,9 +27,7 @@ const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); >reduce : Symbol(Array.reduce, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >accu : Symbol(accu, Decl(destructuringTuple.ts, 10, 34)) >el : Symbol(el, Decl(destructuringTuple.ts, 10, 39)) ->accu.concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >accu : Symbol(accu, Decl(destructuringTuple.ts, 10, 34)) ->concat : Symbol(Array.concat, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) >el : Symbol(el, Decl(destructuringTuple.ts, 10, 39)) const [oops2] = [1, 2, 3].reduce((acc: number[], e) => acc.concat(e), []); diff --git a/tests/baselines/reference/destructuringTuple.types b/tests/baselines/reference/destructuringTuple.types index 270f5e9fa405b..36538fe41fb4c 100644 --- a/tests/baselines/reference/destructuringTuple.types +++ b/tests/baselines/reference/destructuringTuple.types @@ -26,20 +26,20 @@ declare var receiver: typeof tuple; const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); >oops1 : any ->[1, 2, 3].reduce((accu, el) => accu.concat(el), []) : number +>[1, 2, 3].reduce((accu, el) => accu.concat(el), []) : unknown >[1, 2, 3].reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >[1, 2, 3] : number[] >1 : 1 >2 : 2 >3 : 3 >reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } ->(accu, el) => accu.concat(el) : (accu: [], el: number) => never[] ->accu : [] +>(accu, el) => accu.concat(el) : (accu: unknown, el: number) => any +>accu : unknown >el : number ->accu.concat(el) : never[] ->accu.concat : { (...items: ConcatArray[]): never[]; (...items: ConcatArray[]): never[]; } ->accu : [] ->concat : { (...items: ConcatArray[]): never[]; (...items: ConcatArray[]): never[]; } +>accu.concat(el) : any +>accu.concat : any +>accu : unknown +>concat : any >el : number >[] : never[] diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly1.types b/tests/baselines/reference/fixingTypeParametersRepeatedly1.types index 43403eaabe3f2..98b8bc63c602c 100644 --- a/tests/baselines/reference/fixingTypeParametersRepeatedly1.types +++ b/tests/baselines/reference/fixingTypeParametersRepeatedly1.types @@ -35,7 +35,7 @@ declare function g(); >g : { (x: T, y: (p: T) => T, z: (p: T) => T): T; (): any; } g("", x => null, x => x.toLowerCase()); ->g("", x => null, x => x.toLowerCase()) : any +>g("", x => null, x => x.toLowerCase()) : string >g : { (x: T, y: (p: T) => T, z: (p: T) => T): T; (): any; } >"" : "" >x => null : (x: string) => any diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt b/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt index fe3cfc17c435b..799646ff47897 100644 --- a/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt +++ b/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt @@ -1,5 +1,9 @@ fixingTypeParametersRepeatedly2.ts(11,32): error TS2741: Property 'toBase' is missing in type 'Base' but required in type 'Derived'. -fixingTypeParametersRepeatedly2.ts(17,5): error TS2403: Subsequent variable declarations must have the same type. Variable 'result' must be of type 'Derived', but here has type 'Base'. +fixingTypeParametersRepeatedly2.ts(17,32): error TS2769: No overload matches this call. + Overload 1 of 2, '(x: Derived, func: (p: Derived) => Derived): Derived', gave the following error. + Type 'Base' is not assignable to type 'Derived'. + Overload 2 of 2, '(x: Derived, func: (p: Derived) => Derived): Derived', gave the following error. + Type 'Base' is not assignable to type 'Derived'. ==== fixingTypeParametersRepeatedly2.ts (2 errors) ==== @@ -24,6 +28,11 @@ fixingTypeParametersRepeatedly2.ts(17,5): error TS2403: Subsequent variable decl declare function bar(x: T, func: (p: T) => T): T; declare function bar(x: T, func: (p: T) => T): T; var result = bar(derived, d => d.toBase()); - ~~~~~~ -!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'result' must be of type 'Derived', but here has type 'Base'. -!!! related TS6203 fixingTypeParametersRepeatedly2.ts:11:5: 'result' was also declared here. \ No newline at end of file + ~~~~~~~~~~ +!!! error TS2769: No overload matches this call. +!!! error TS2769: Overload 1 of 2, '(x: Derived, func: (p: Derived) => Derived): Derived', gave the following error. +!!! error TS2769: Type 'Base' is not assignable to type 'Derived'. +!!! error TS2769: Overload 2 of 2, '(x: Derived, func: (p: Derived) => Derived): Derived', gave the following error. +!!! error TS2769: Type 'Base' is not assignable to type 'Derived'. +!!! related TS6502 fixingTypeParametersRepeatedly2.ts:15:37: The expected type comes from the return type of this signature. +!!! related TS6502 fixingTypeParametersRepeatedly2.ts:16:37: The expected type comes from the return type of this signature. \ No newline at end of file diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly2.types b/tests/baselines/reference/fixingTypeParametersRepeatedly2.types index be32c7a69da8a..8df2a421b747f 100644 --- a/tests/baselines/reference/fixingTypeParametersRepeatedly2.types +++ b/tests/baselines/reference/fixingTypeParametersRepeatedly2.types @@ -47,7 +47,7 @@ declare function bar(x: T, func: (p: T) => T): T; var result = bar(derived, d => d.toBase()); >result : Derived ->bar(derived, d => d.toBase()) : Base +>bar(derived, d => d.toBase()) : Derived >bar : { (x: T, func: (p: T) => T): T; (x: T_1, func: (p: T_1) => T_1): T_1; } >derived : Derived >d => d.toBase() : (d: Derived) => Base diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly3.types b/tests/baselines/reference/fixingTypeParametersRepeatedly3.types index e84f62399fcc9..5ce0e4ca25944 100644 --- a/tests/baselines/reference/fixingTypeParametersRepeatedly3.types +++ b/tests/baselines/reference/fixingTypeParametersRepeatedly3.types @@ -46,8 +46,8 @@ declare function bar(x: T, func: (p: T) => T): T; >p : T var result2 = bar(derived, d => d.toBase()); ->result2 : Base ->bar(derived, d => d.toBase()) : Base +>result2 : Derived +>bar(derived, d => d.toBase()) : Derived >bar : { (x: T, func: (p: T) => T): T; (x: T_1, func: (p: T_1) => T_1): T_1; } >derived : Derived >d => d.toBase() : (d: Derived) => Base diff --git a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.errors.txt b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.errors.txt new file mode 100644 index 0000000000000..e0211a09473ba --- /dev/null +++ b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.errors.txt @@ -0,0 +1,34 @@ +overloadedConstructorFixesInferencesAppropriately.ts(26,32): error TS2339: Property 'success' does not exist on type '{}'. + + +==== overloadedConstructorFixesInferencesAppropriately.ts (1 errors) ==== + interface Box { + v: T; + } + + interface ErrorResult { + readonly error: true + } + + interface AsyncLoaderProps { + readonly asyncLoad: () => Box; + readonly children: (result: Exclude) => string; + } + + class AsyncLoader { + constructor(props: string, context: any); + constructor(props: AsyncLoaderProps); + constructor(...args: any[]) {} + } + + function load(): Box<{ success: true } | ErrorResult> { + return null as any; + } + + new AsyncLoader({ + asyncLoad: load, + children: result => result.success as any, + ~~~~~~~ +!!! error TS2339: Property 'success' does not exist on type '{}'. + }); // should work fine + \ No newline at end of file diff --git a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols index d547c072ef6ca..1448ef2a2bf42 100644 --- a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols +++ b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols @@ -70,9 +70,7 @@ new AsyncLoader({ children: result => result.success as any, >children : Symbol(children, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 24, 20)) >result : Symbol(result, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 25, 13)) ->result.success : Symbol(success, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 19, 22)) >result : Symbol(result, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 25, 13)) ->success : Symbol(success, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 19, 22)) }); // should work fine diff --git a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types index 29ab9ea9b9b9b..ad41689f296b4 100644 --- a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types +++ b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types @@ -45,22 +45,22 @@ function load(): Box<{ success: true } | ErrorResult> { } new AsyncLoader({ ->new AsyncLoader({ asyncLoad: load, children: result => result.success as any,}) : AsyncLoader +>new AsyncLoader({ asyncLoad: load, children: result => result.success as any,}) : AsyncLoader<{}> >AsyncLoader : typeof AsyncLoader ->{ asyncLoad: load, children: result => result.success as any,} : { asyncLoad: () => Box; children: (result: { success: true; }) => any; } +>{ asyncLoad: load, children: result => result.success as any,} : { asyncLoad: () => Box; children: (result: {}) => any; } asyncLoad: load, >asyncLoad : () => Box >load : () => Box children: result => result.success as any, ->children : (result: { success: true; }) => any ->result => result.success as any : (result: { success: true; }) => any ->result : { success: true; } +>children : (result: {}) => any +>result => result.success as any : (result: {}) => any +>result : {} >result.success as any : any ->result.success : true ->result : { success: true; } ->success : true +>result.success : any +>result : {} +>success : any }); // should work fine diff --git a/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.errors.txt b/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.errors.txt index d6f3cd897e67a..98137ac6dc931 100644 --- a/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.errors.txt +++ b/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.errors.txt @@ -1,44 +1,12 @@ -overloadresolutionWithConstraintCheckingDeferred.ts(14,22): error TS2769: No overload matches this call. - Overload 1 of 3, '(arg: (x: D) => number): string', gave the following error. - Type 'G' is not assignable to type 'number'. - Overload 2 of 3, '(arg: (x: C) => any): string', gave the following error. - Argument of type '(x: D) => G' is not assignable to parameter of type '(x: C) => any'. - Types of parameters 'x' and 'x' are incompatible. - Property 'q' is missing in type 'C' but required in type 'D'. - Overload 3 of 3, '(arg: (x: B) => any): number', gave the following error. - Argument of type '(x: D) => G' is not assignable to parameter of type '(x: B) => any'. - Types of parameters 'x' and 'x' are incompatible. - Property 'q' is missing in type 'B' but required in type 'D'. -overloadresolutionWithConstraintCheckingDeferred.ts(14,37): error TS2345: Argument of type 'D' is not assignable to parameter of type 'A'. - Property 'x' is missing in type 'D' but required in type 'A'. -overloadresolutionWithConstraintCheckingDeferred.ts(16,23): error TS2769: No overload matches this call. - Overload 1 of 3, '(arg: (x: D) => number): string', gave the following error. - Type 'G' is not assignable to type 'number'. - Overload 2 of 3, '(arg: (x: C) => any): string', gave the following error. - Argument of type '(x: D) => G' is not assignable to parameter of type '(x: C) => any'. - Types of parameters 'x' and 'x' are incompatible. - Type 'C' is not assignable to type 'D'. - Overload 3 of 3, '(arg: (x: B) => any): number', gave the following error. - Argument of type '(x: D) => G' is not assignable to parameter of type '(x: B) => any'. - Types of parameters 'x' and 'x' are incompatible. - Type 'B' is not assignable to type 'D'. -overloadresolutionWithConstraintCheckingDeferred.ts(16,38): error TS2344: Type 'D' does not satisfy the constraint 'A'. -overloadresolutionWithConstraintCheckingDeferred.ts(18,27): error TS2769: No overload matches this call. - Overload 1 of 3, '(arg: (x: D) => number): string', gave the following error. - Argument of type '(x: D) => G' is not assignable to parameter of type '(x: D) => number'. - Type 'G' is not assignable to type 'number'. - Overload 2 of 3, '(arg: (x: C) => any): string', gave the following error. - Argument of type '(x: D) => G' is not assignable to parameter of type '(x: C) => any'. - Types of parameters 'x' and 'x' are incompatible. - Type 'C' is not assignable to type 'D'. - Overload 3 of 3, '(arg: (x: B) => any): number', gave the following error. - Argument of type '(x: D) => G' is not assignable to parameter of type '(x: B) => any'. - Types of parameters 'x' and 'x' are incompatible. - Type 'B' is not assignable to type 'D'. -overloadresolutionWithConstraintCheckingDeferred.ts(19,14): error TS2344: Type 'D' does not satisfy the constraint 'A'. +overloadresolutionWithConstraintCheckingDeferred.ts(14,5): error TS2322: Type 'string' is not assignable to type 'number'. +overloadresolutionWithConstraintCheckingDeferred.ts(14,37): error TS2345: Argument of type 'C' is not assignable to parameter of type 'A'. + Property 'x' is missing in type 'C' but required in type 'A'. +overloadresolutionWithConstraintCheckingDeferred.ts(16,5): error TS2322: Type 'string' is not assignable to type 'number'. +overloadresolutionWithConstraintCheckingDeferred.ts(16,38): error TS2344: Type 'C' does not satisfy the constraint 'A'. +overloadresolutionWithConstraintCheckingDeferred.ts(19,14): error TS2344: Type 'C' does not satisfy the constraint 'A'. -==== overloadresolutionWithConstraintCheckingDeferred.ts (6 errors) ==== +==== overloadresolutionWithConstraintCheckingDeferred.ts (5 errors) ==== interface A { x } interface B { x; y } interface C { z } @@ -53,60 +21,23 @@ overloadresolutionWithConstraintCheckingDeferred.ts(19,14): error TS2344: Type ' declare function foo(arg: (x: B) => any): number; var result: number = foo(x => new G(x)); // x has type D, new G(x) fails, so first overload is picked. - ~~~ -!!! error TS2769: No overload matches this call. -!!! error TS2769: Overload 1 of 3, '(arg: (x: D) => number): string', gave the following error. -!!! error TS2769: Type 'G' is not assignable to type 'number'. -!!! error TS2769: Overload 2 of 3, '(arg: (x: C) => any): string', gave the following error. -!!! error TS2769: Argument of type '(x: D) => G' is not assignable to parameter of type '(x: C) => any'. -!!! error TS2769: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2769: Property 'q' is missing in type 'C' but required in type 'D'. -!!! error TS2769: Overload 3 of 3, '(arg: (x: B) => any): number', gave the following error. -!!! error TS2769: Argument of type '(x: D) => G' is not assignable to parameter of type '(x: B) => any'. -!!! error TS2769: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2769: Property 'q' is missing in type 'B' but required in type 'D'. -!!! related TS6502 overloadresolutionWithConstraintCheckingDeferred.ts:10:27: The expected type comes from the return type of this signature. -!!! related TS2728 overloadresolutionWithConstraintCheckingDeferred.ts:4:15: 'q' is declared here. -!!! related TS2728 overloadresolutionWithConstraintCheckingDeferred.ts:4:15: 'q' is declared here. + ~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. ~ -!!! error TS2345: Argument of type 'D' is not assignable to parameter of type 'A'. -!!! error TS2345: Property 'x' is missing in type 'D' but required in type 'A'. +!!! error TS2345: Argument of type 'C' is not assignable to parameter of type 'A'. +!!! error TS2345: Property 'x' is missing in type 'C' but required in type 'A'. !!! related TS2728 overloadresolutionWithConstraintCheckingDeferred.ts:1:15: 'x' is declared here. var result2: number = foo(x => new G(x)); // x has type D, new G(x) fails, so first overload is picked. - ~~~ -!!! error TS2769: No overload matches this call. -!!! error TS2769: Overload 1 of 3, '(arg: (x: D) => number): string', gave the following error. -!!! error TS2769: Type 'G' is not assignable to type 'number'. -!!! error TS2769: Overload 2 of 3, '(arg: (x: C) => any): string', gave the following error. -!!! error TS2769: Argument of type '(x: D) => G' is not assignable to parameter of type '(x: C) => any'. -!!! error TS2769: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2769: Type 'C' is not assignable to type 'D'. -!!! error TS2769: Overload 3 of 3, '(arg: (x: B) => any): number', gave the following error. -!!! error TS2769: Argument of type '(x: D) => G' is not assignable to parameter of type '(x: B) => any'. -!!! error TS2769: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2769: Type 'B' is not assignable to type 'D'. -!!! related TS6502 overloadresolutionWithConstraintCheckingDeferred.ts:10:27: The expected type comes from the return type of this signature. + ~~~~~~~ +!!! error TS2322: Type 'string' is not assignable to type 'number'. ~~~~~~~~ -!!! error TS2344: Type 'D' does not satisfy the constraint 'A'. +!!! error TS2344: Type 'C' does not satisfy the constraint 'A'. var result3: string = foo(x => { // x has type D - ~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2769: No overload matches this call. -!!! error TS2769: Overload 1 of 3, '(arg: (x: D) => number): string', gave the following error. -!!! error TS2769: Argument of type '(x: D) => G' is not assignable to parameter of type '(x: D) => number'. -!!! error TS2769: Type 'G' is not assignable to type 'number'. -!!! error TS2769: Overload 2 of 3, '(arg: (x: C) => any): string', gave the following error. -!!! error TS2769: Argument of type '(x: D) => G' is not assignable to parameter of type '(x: C) => any'. -!!! error TS2769: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2769: Type 'C' is not assignable to type 'D'. -!!! error TS2769: Overload 3 of 3, '(arg: (x: B) => any): number', gave the following error. -!!! error TS2769: Argument of type '(x: D) => G' is not assignable to parameter of type '(x: B) => any'. -!!! error TS2769: Types of parameters 'x' and 'x' are incompatible. -!!! error TS2769: Type 'B' is not assignable to type 'D'. var y: G; // error that D does not satisfy constraint, y is of type G, entire call to foo is an error ~~~~~~~~ -!!! error TS2344: Type 'D' does not satisfy the constraint 'A'. +!!! error TS2344: Type 'C' does not satisfy the constraint 'A'. return y; }); \ No newline at end of file diff --git a/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.types b/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.types index efb2d1a013e8f..1d0afa183045d 100644 --- a/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.types +++ b/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.types @@ -38,38 +38,38 @@ declare function foo(arg: (x: B) => any): number; var result: number = foo(x => new G(x)); // x has type D, new G(x) fails, so first overload is picked. >result : number ->foo(x => new G(x)) : never +>foo(x => new G(x)) : string >foo : { (arg: (x: D) => number): string; (arg: (x: C) => any): string; (arg: (x: B) => any): number; } ->x => new G(x) : (x: D) => G ->x : D +>x => new G(x) : (x: C) => G +>x : C >new G(x) : G >G : typeof G ->x : D +>x : C var result2: number = foo(x => new G(x)); // x has type D, new G(x) fails, so first overload is picked. >result2 : number ->foo(x => new G(x)) : never +>foo(x => new G(x)) : string >foo : { (arg: (x: D) => number): string; (arg: (x: C) => any): string; (arg: (x: B) => any): number; } ->x => new G(x) : (x: D) => G ->x : D ->new G(x) : G +>x => new G(x) : (x: C) => G +>x : C +>new G(x) : G >G : typeof G ->x : D ->x : D +>x : C +>x : C var result3: string = foo(x => { // x has type D >result3 : string ->foo(x => { // x has type D var y: G; // error that D does not satisfy constraint, y is of type G, entire call to foo is an error return y;}) : never +>foo(x => { // x has type D var y: G; // error that D does not satisfy constraint, y is of type G, entire call to foo is an error return y;}) : string >foo : { (arg: (x: D) => number): string; (arg: (x: C) => any): string; (arg: (x: B) => any): number; } ->x => { // x has type D var y: G; // error that D does not satisfy constraint, y is of type G, entire call to foo is an error return y;} : (x: D) => G ->x : D +>x => { // x has type D var y: G; // error that D does not satisfy constraint, y is of type G, entire call to foo is an error return y;} : (x: C) => G +>x : C var y: G; // error that D does not satisfy constraint, y is of type G, entire call to foo is an error ->y : G ->x : D +>y : G +>x : C return y; ->y : G +>y : G }); diff --git a/tests/baselines/reference/overloadsWithProvisionalErrors.errors.txt b/tests/baselines/reference/overloadsWithProvisionalErrors.errors.txt index 2cbb7768d07e8..3e7779b5bb99d 100644 --- a/tests/baselines/reference/overloadsWithProvisionalErrors.errors.txt +++ b/tests/baselines/reference/overloadsWithProvisionalErrors.errors.txt @@ -1,12 +1,12 @@ overloadsWithProvisionalErrors.ts(6,1): error TS2769: No overload matches this call. Overload 1 of 2, '(s: string): number', gave the following error. - Argument of type '(s: string) => {}' is not assignable to parameter of type 'string'. + Argument of type '(s: any) => {}' is not assignable to parameter of type 'string'. Overload 2 of 2, '(lambda: (s: string) => { a: number; b: number; }): string', gave the following error. Type '{}' is missing the following properties from type '{ a: number; b: number; }': a, b overloadsWithProvisionalErrors.ts(7,17): error TS2304: Cannot find name 'blah'. overloadsWithProvisionalErrors.ts(8,1): error TS2769: No overload matches this call. Overload 1 of 2, '(s: string): number', gave the following error. - Argument of type '(s: string) => { a: any; }' is not assignable to parameter of type 'string'. + Argument of type '(s: any) => { a: any; }' is not assignable to parameter of type 'string'. Overload 2 of 2, '(lambda: (s: string) => { a: number; b: number; }): string', gave the following error. Property 'b' is missing in type '{ a: any; }' but required in type '{ a: number; b: number; }'. overloadsWithProvisionalErrors.ts(8,17): error TS2304: Cannot find name 'blah'. @@ -22,7 +22,7 @@ overloadsWithProvisionalErrors.ts(8,17): error TS2304: Cannot find name 'blah'. ~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(s: string): number', gave the following error. -!!! error TS2769: Argument of type '(s: string) => {}' is not assignable to parameter of type 'string'. +!!! error TS2769: Argument of type '(s: any) => {}' is not assignable to parameter of type 'string'. !!! error TS2769: Overload 2 of 2, '(lambda: (s: string) => { a: number; b: number; }): string', gave the following error. !!! error TS2769: Type '{}' is missing the following properties from type '{ a: number; b: number; }': a, b !!! related TS6502 overloadsWithProvisionalErrors.ts:3:14: The expected type comes from the return type of this signature. @@ -33,7 +33,7 @@ overloadsWithProvisionalErrors.ts(8,17): error TS2304: Cannot find name 'blah'. ~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(s: string): number', gave the following error. -!!! error TS2769: Argument of type '(s: string) => { a: any; }' is not assignable to parameter of type 'string'. +!!! error TS2769: Argument of type '(s: any) => { a: any; }' is not assignable to parameter of type 'string'. !!! error TS2769: Overload 2 of 2, '(lambda: (s: string) => { a: number; b: number; }): string', gave the following error. !!! error TS2769: Property 'b' is missing in type '{ a: any; }' but required in type '{ a: number; b: number; }'. !!! related TS2728 overloadsWithProvisionalErrors.ts:3:42: 'b' is declared here. diff --git a/tests/baselines/reference/overloadsWithProvisionalErrors.types b/tests/baselines/reference/overloadsWithProvisionalErrors.types index 2a14c1ebc497e..359f15b626c21 100644 --- a/tests/baselines/reference/overloadsWithProvisionalErrors.types +++ b/tests/baselines/reference/overloadsWithProvisionalErrors.types @@ -18,8 +18,8 @@ var func: { func(s => ({})); // Error for no applicable overload (object type is missing a and b) >func(s => ({})) : never >func : { (s: string): number; (lambda: (s: string) => { a: number; b: number; }): string; } ->s => ({}) : (s: string) => {} ->s : string +>s => ({}) : (s: any) => {} +>s : any >({}) : {} >{} : {} @@ -38,8 +38,8 @@ func(s => ({ a: blah, b: 3 })); // Only error inside the function, but not outsi func(s => ({ a: blah })); // Two errors here, one for blah not being defined, and one for the overload since it would not be applicable anyway >func(s => ({ a: blah })) : never >func : { (s: string): number; (lambda: (s: string) => { a: number; b: number; }): string; } ->s => ({ a: blah }) : (s: string) => { a: any; } ->s : string +>s => ({ a: blah }) : (s: any) => { a: any; } +>s : any >({ a: blah }) : { a: any; } >{ a: blah } : { a: any; } >a : any diff --git a/tests/baselines/reference/parenthesizedContexualTyping1.types b/tests/baselines/reference/parenthesizedContexualTyping1.types index 7f7fe071a666e..75c3d892c8014 100644 --- a/tests/baselines/reference/parenthesizedContexualTyping1.types +++ b/tests/baselines/reference/parenthesizedContexualTyping1.types @@ -130,100 +130,100 @@ var h = fun((((x => x))), ((x => x)), 10); // Ternaries in parens var i = fun((Math.random() < 0.5 ? x => x : x => undefined), 10); ->i : any ->fun((Math.random() < 0.5 ? x => x : x => undefined), 10) : any +>i : unknown +>fun((Math.random() < 0.5 ? x => x : x => undefined), 10) : unknown >fun : { (g: (x: T) => T, x: T): T; (g: (x: T_1) => T_1, h: (y: T_1) => T_1, x: T_1): T_1; } ->(Math.random() < 0.5 ? x => x : x => undefined) : (x: number) => any ->Math.random() < 0.5 ? x => x : x => undefined : (x: number) => any +>(Math.random() < 0.5 ? x => x : x => undefined) : (x: unknown) => any +>Math.random() < 0.5 ? x => x : x => undefined : (x: unknown) => any >Math.random() < 0.5 : boolean >Math.random() : number >Math.random : () => number >Math : Math >random : () => number >0.5 : 0.5 ->x => x : (x: number) => number ->x : number ->x : number ->x => undefined : (x: number) => any ->x : number +>x => x : (x: unknown) => unknown +>x : unknown +>x : unknown +>x => undefined : (x: unknown) => any +>x : unknown >undefined : undefined >10 : 10 var j = fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), 10); ->j : any ->fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), 10) : any +>j : unknown +>fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), 10) : unknown >fun : { (g: (x: T) => T, x: T): T; (g: (x: T_1) => T_1, h: (y: T_1) => T_1, x: T_1): T_1; } ->(Math.random() < 0.5 ? (x => x) : (x => undefined)) : (x: number) => any ->Math.random() < 0.5 ? (x => x) : (x => undefined) : (x: number) => any +>(Math.random() < 0.5 ? (x => x) : (x => undefined)) : (x: unknown) => any +>Math.random() < 0.5 ? (x => x) : (x => undefined) : (x: unknown) => any >Math.random() < 0.5 : boolean >Math.random() : number >Math.random : () => number >Math : Math >random : () => number >0.5 : 0.5 ->(x => x) : (x: number) => number ->x => x : (x: number) => number ->x : number ->x : number ->(x => undefined) : (x: number) => any ->x => undefined : (x: number) => any ->x : number +>(x => x) : (x: unknown) => unknown +>x => x : (x: unknown) => unknown +>x : unknown +>x : unknown +>(x => undefined) : (x: unknown) => any +>x => undefined : (x: unknown) => any +>x : unknown >undefined : undefined >10 : 10 var k = fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), x => x, 10); ->k : any ->fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), x => x, 10) : any +>k : unknown +>fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), x => x, 10) : unknown >fun : { (g: (x: T) => T, x: T): T; (g: (x: T_1) => T_1, h: (y: T_1) => T_1, x: T_1): T_1; } ->(Math.random() < 0.5 ? (x => x) : (x => undefined)) : (x: number) => any ->Math.random() < 0.5 ? (x => x) : (x => undefined) : (x: number) => any +>(Math.random() < 0.5 ? (x => x) : (x => undefined)) : (x: unknown) => any +>Math.random() < 0.5 ? (x => x) : (x => undefined) : (x: unknown) => any >Math.random() < 0.5 : boolean >Math.random() : number >Math.random : () => number >Math : Math >random : () => number >0.5 : 0.5 ->(x => x) : (x: number) => number ->x => x : (x: number) => number ->x : number ->x : number ->(x => undefined) : (x: number) => any ->x => undefined : (x: number) => any ->x : number +>(x => x) : (x: unknown) => unknown +>x => x : (x: unknown) => unknown +>x : unknown +>x : unknown +>(x => undefined) : (x: unknown) => any +>x => undefined : (x: unknown) => any +>x : unknown >undefined : undefined ->x => x : (x: number) => number ->x : number ->x : number +>x => x : (x: unknown) => unknown +>x : unknown +>x : unknown >10 : 10 var l = fun(((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))), ((x => x)), 10); ->l : any ->fun(((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))), ((x => x)), 10) : any +>l : unknown +>fun(((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))), ((x => x)), 10) : unknown >fun : { (g: (x: T) => T, x: T): T; (g: (x: T_1) => T_1, h: (y: T_1) => T_1, x: T_1): T_1; } ->((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))) : (x: number) => any ->(Math.random() < 0.5 ? ((x => x)) : ((x => undefined))) : (x: number) => any ->Math.random() < 0.5 ? ((x => x)) : ((x => undefined)) : (x: number) => any +>((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))) : (x: unknown) => any +>(Math.random() < 0.5 ? ((x => x)) : ((x => undefined))) : (x: unknown) => any +>Math.random() < 0.5 ? ((x => x)) : ((x => undefined)) : (x: unknown) => any >Math.random() < 0.5 : boolean >Math.random() : number >Math.random : () => number >Math : Math >random : () => number >0.5 : 0.5 ->((x => x)) : (x: number) => number ->(x => x) : (x: number) => number ->x => x : (x: number) => number ->x : number ->x : number ->((x => undefined)) : (x: number) => any ->(x => undefined) : (x: number) => any ->x => undefined : (x: number) => any ->x : number +>((x => x)) : (x: unknown) => unknown +>(x => x) : (x: unknown) => unknown +>x => x : (x: unknown) => unknown +>x : unknown +>x : unknown +>((x => undefined)) : (x: unknown) => any +>(x => undefined) : (x: unknown) => any +>x => undefined : (x: unknown) => any +>x : unknown >undefined : undefined ->((x => x)) : (x: number) => number ->(x => x) : (x: number) => number ->x => x : (x: number) => number ->x : number ->x : number +>((x => x)) : (x: unknown) => unknown +>(x => x) : (x: unknown) => unknown +>x => x : (x: unknown) => unknown +>x : unknown +>x : unknown >10 : 10 var lambda1: (x: number) => number = x => x; diff --git a/tests/baselines/reference/ramdaToolsNoInfinite2.errors.txt b/tests/baselines/reference/ramdaToolsNoInfinite2.errors.txt new file mode 100644 index 0000000000000..0b66551b2f68b --- /dev/null +++ b/tests/baselines/reference/ramdaToolsNoInfinite2.errors.txt @@ -0,0 +1,581 @@ +ramdaToolsNoInfinite2.ts(286,76): error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' does not satisfy the constraint 'List'. + Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' is missing the following properties from type 'readonly any[]': length, concat, join, slice, and 9 more. +ramdaToolsNoInfinite2.ts(327,90): error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' does not satisfy the constraint 'List'. + Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' is missing the following properties from type 'readonly any[]': length, concat, join, slice, and 9 more. + + +==== ramdaToolsNoInfinite2.ts (2 errors) ==== + declare module "Any/Kind" { + import { Extends } from "Any/Extends"; + import { List } from "List/List"; + + export type Kind = Extends extends 1 ? 'function' : Extends extends 1 ? 'array' : Extends extends 1 ? 'object' : Extends extends 1 ? 'string' : Extends extends 1 ? 'number' : Extends extends 1 ? 'boolean' : 'unknown'; + } + declare module "Any/Compute" { + export type Compute = A extends Function ? A : { + [K in keyof A]: A[K]; + } & {}; + } + declare module "Object/Pick" { + import { Key } from "Any/Key"; + + type __Pick = { + [P in K]: O[P]; + } & {}; + + export type _Pick = __Pick; + + export type Pick = O extends unknown ? _Pick : never; + } + declare module "Object/Keys" { + import { Keys as UKeys } from "Union/Keys"; + + export type Keys = UKeys; + } + declare module "Object/Omit" { + import { _Pick } from "Object/Pick"; + import { Exclude } from "Union/Exclude"; + import { Key } from "Any/Key"; + import { Keys } from "Object/Keys"; + export type _Omit = _Pick, K>>; + + export type Omit = O extends unknown ? _Omit : never; + } + declare module "Object/At" { + import { Key } from "Any/Key"; + import { Boolean } from "Boolean/Boolean"; + + type AtStrict = [K & keyof O] extends [never] ? never : O[K & keyof O]; + + type AtLoose = O extends unknown ? AtStrict : never; + + export type At = { + 1: AtStrict; + 0: AtLoose; + }[strict]; + } + declare module "Boolean/Boolean" { + export type Boolean = True | False; + + export type True = 1; + + export type False = 0; + } + declare module "Boolean/Not" { + import { Boolean } from "Boolean/Boolean"; + + export type Not = { + 0: 1; + 1: 0; + }[B]; + } + declare module "Union/Has" { + import { Union } from "Union/Union"; + import { Not } from "Boolean/Not"; + import { Extends } from "Any/Extends"; + + export type Has = Not, U1>>; + } + declare module "Union/Union" { + export type Union = any; + } + declare module "Union/Exclude" { + import { Union } from "Union/Union"; + + export type Exclude = U extends M ? never : U; + } + declare module "Any/_Internal" { + import { _NumberOf } from "Number/NumberOf"; + + export type Match = 'default' | 'implements->' | '<-implements' | 'extends->' | '<-extends' | 'equals'; + + export type NumberOf = N extends number ? _NumberOf : N; + } + declare module "Any/Implements" { + import { Extends } from "Any/Extends"; + + export type Implements = Extends extends 1 ? 1 : 0; + } + declare module "Any/Key" { + export type Key = string | number | symbol; + } + declare module "Union/Keys" { + import { Union } from "Union/Union"; + import { Key } from "Any/Key"; + + export type Keys = (U extends unknown ? keyof U : never) & Key; + } + declare module "List/ObjectOf" { + import { _Omit } from "Object/Omit"; + import { Has } from "Union/Has"; + import { At } from "Object/At"; + import { List } from "List/List"; + + export type _ObjectOf = Has extends 1 ? number extends At ? _Omit> : _Omit : L; + + export type ObjectOf = L extends unknown ? _ObjectOf : never; + } + declare module "List/Keys" { + import { Exclude } from "Union/Exclude"; + import { List } from "List/List"; + import { Keys as UKeys } from "Union/Keys"; + + export type Keys = Exclude, keyof any[]> | number; + } + declare module "Object/Merge" { + import { _Omit } from "Object/Omit"; + import { At } from "Object/At"; + import { Compute } from "Any/Compute"; + import { Depth } from "Object/_Internal"; + import { Kind } from "Any/Kind"; + + export type MergeFlat = Compute>; + + export type MergeDeep = (Kind<(O | O1)> extends 'object' ? MergeFlat extends infer M ? { + [K in keyof M]: MergeDeep>; + } & {} : never : O); + + export type Merge = { + 'flat': MergeFlat; + 'deep': MergeDeep; + }[depth]; + } + declare module "Union/NonNullable" { + import { Exclude } from "Union/Exclude"; + import { Union } from "Union/Union"; + + export type NonNullable = Exclude; + } + declare module "Object/ListOf" { + import { IterationOf } from "Iteration/IterationOf"; + import { Iteration } from "Iteration/Iteration"; + import { Cast } from "Any/Cast"; + import { Key } from "Iteration/Key"; + import { Next } from "Iteration/Next"; + import { _Append } from "List/Append"; + import { Exclude } from "Union/Exclude"; + import { List } from "List/List"; + import { Extends } from "Any/Extends"; + + type PickIfEntry = Key extends keyof O ? _Append, keyof O>]> : LN; + + type __ListOf> = { + 0: __ListOf>, PickIfEntry, Next>; + 1: LN; + }[Extends<[K], [never]>]; + + export type _ListOf = __ListOf extends infer X ? Cast : never; + + export type ListOf = O extends unknown ? _ListOf : never; + } + declare module "Object/NonNullable" { + import { MergeFlat } from "Object/Merge"; + import { NonNullable as UNonNullable } from "Union/NonNullable"; + import { Depth } from "Object/_Internal"; + import { Pick } from "Object/Pick"; + import { Key } from "Any/Key"; + import { Implements } from "Any/Implements"; + import { Keys } from "Object/Keys"; + + export type NonNullableFlat = { + [K in keyof O]: UNonNullable; + } & {}; + + export type NonNullableDeep = { + [K in keyof O]: NonNullableDeep>; + }; + + type NonNullablePart = { + 'flat': NonNullableFlat; + 'deep': NonNullableDeep; + }[depth]; + + export type NonNullable = { + 1: NonNullablePart; + 0: MergeFlat, depth>, O>; + }[Implements, K>] & {}; + } + declare module "Object/Overwrite" { + export type Overwrite = { + [K in keyof O]: K extends keyof O1 ? O1[K] : O[K]; + } & {}; + } + declare module "Number/_Internal" { + import { IterationMap } from "Iteration/IterationOf"; + import { Format } from "Iteration/Format"; + + export type Formats = 'b' | 'n' | 's'; + + type KnownIterationMapKeys = '-40' | '-39' | '-38' | '-37' | '-36' | '-35' | '-34' | '-33' | '-32' | '-31' | '-30' | '-29' | '-28' | '-27' | '-26' | '-25' | '-24' | '-23' | '-22' | '-21' | '-20' | '-19' | '-18' | '-17' | '-16' | '-15' | '-14' | '-13' | '-12' | '-11' | '-10' | '-9' | '-8' | '-7' | '-6' | '-5' | '-4' | '-3' | '-2' | '-1' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | '13' | '14' | '15' | '16' | '17' | '18' | '19' | '20' | '21' | '22' | '23' | '24' | '25' | '26' | '27' | '28' | '29' | '30' | '31' | '32' | '33' | '34' | '35' | '36' | '37' | '38' | '39' | '40'; + + type PositiveIterationKeys = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | '13' | '14' | '15' | '16' | '17' | '18' | '19' | '20' | '21' | '22' | '23' | '24' | '25' | '26' | '27' | '28' | '29' | '30' | '31' | '32' | '33' | '34' | '35' | '36' | '37' | '38' | '39' | '40'; + + type NegativeIterationKeys = '-40' | '-39' | '-38' | '-37' | '-36' | '-35' | '-34' | '-33' | '-32' | '-31' | '-30' | '-29' | '-28' | '-27' | '-26' | '-25' | '-24' | '-23' | '-22' | '-21' | '-20' | '-19' | '-18' | '-17' | '-16' | '-15' | '-14' | '-13' | '-12' | '-11' | '-10' | '-9' | '-8' | '-7' | '-6' | '-5' | '-4' | '-3' | '-2' | '-1'; + + export type Numbers = { + 'string': { + 'all': Format; + '+': Format; + '-': Format; + '0': Format; + }; + 'number': { + 'all': Format; + '+': Format; + '-': Format; + '0': Format; + }; + }; + } + declare module "Number/Number" { + export type Number = string; + } + declare module "Iteration/_Internal" { + export type Formats = 'n' | 's'; + export type Way = '->' | '<-'; + } + declare module "List/Prepend" { + import { List } from "List/List"; + + export type Prepend = ((head: A, ...args: L) => any) extends ((...args: infer U) => any) ? U : L; + } + declare module "List/_Internal" { + import { Overwrite } from "Object/Overwrite"; + import { List } from "List/List"; + + export type Naked = Overwrite, L>; + } + declare module "List/Tail" { + import { List } from "List/List"; + + export type Tail = ((...t: L) => any) extends ((head: any, ...tail: infer LTail) => any) ? LTail : never; + } + declare module "Iteration/Format" { + import { Iteration } from "Iteration/Iteration"; + import { Formats } from "Iteration/_Internal"; + + export type Format = { + 's': I[2]; + 'n': I[3]; + }[fmt]; + } + declare module "Iteration/Pos" { + import { Iteration } from "Iteration/Iteration"; + import { Format } from "Iteration/Format"; + + export type Pos = Format; + } + declare module "List/Append" { + import { _Concat } from "List/Concat"; + import { List } from "List/List"; + + export type _Append = _Concat; + + export type Append = L extends unknown ? A extends unknown ? _Append : never : never; + } + declare module "List/Reverse" { + import { Prepend } from "List/Prepend"; + import { Pos } from "Iteration/Pos"; + import { Next } from "Iteration/Next"; + import { Length } from "List/Length"; + import { IterationOf } from "Iteration/IterationOf"; + import { Iteration } from "Iteration/Iteration"; + import { Cast } from "Any/Cast"; + import { List } from "List/List"; + import { Naked } from "List/_Internal"; + import { Extends } from "Any/Extends"; + + type __Reverse> = { + 0: __Reverse]>, Next>; + 1: LO; + }[Extends, Length>]; + + export type _Reverse = __Reverse, LO> extends infer X ? Cast : never; + ~~~~~~~~ +!!! error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' does not satisfy the constraint 'List'. +!!! error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' is missing the following properties from type 'readonly any[]': length, concat, join, slice, and 9 more. + + export type Reverse = L extends unknown ? LO extends unknown ? _Reverse : never : never; + } + declare module "List/Concat" { + import { _Reverse } from "List/Reverse"; + import { List } from "List/List"; + + export type _Concat = _Reverse<_Reverse, L1>; + + export type Concat = L extends unknown ? L1 extends L1 ? _Concat : never : never; + } + declare module "List/Drop" { + import { Tail } from "List/Tail"; + import { Cast } from "Any/Cast"; + import { IterationOf } from "Iteration/IterationOf"; + import { Iteration } from "Iteration/Iteration"; + import { Number } from "Number/Number"; + import { Way } from "Iteration/_Internal"; + import { List } from "List/List"; + import { Pos } from "Iteration/Pos"; + import { Prev } from "Iteration/Prev"; + import { Prepend } from "List/Prepend"; + import { Naked } from "List/_Internal"; + import { Extends } from "Any/Extends"; + + type DropForth = { + 0: DropForth, Prev>; + 1: L; + }[Extends<0, Pos>]; + + type DropBack, LN extends List = []> = { + 0: DropBack, Prepend]>>; + 1: LN; + }[Extends<-1, Pos>]; + + type __Drop = { + '->': DropForth; + '<-': DropBack; + }[way]; + + export type _Drop = __Drop, IterationOf, way> extends infer X ? Cast : never; + ~~~~~~~~ +!!! error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' does not satisfy the constraint 'List'. +!!! error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' is missing the following properties from type 'readonly any[]': length, concat, join, slice, and 9 more. + + export type Drop = L extends unknown ? N extends unknown ? _Drop : never : never; + } + declare module "List/Length" { + import { NumberOf } from "Number/NumberOf"; + import { Formats } from "Iteration/_Internal"; + import { List } from "List/List"; + + export type Length = { + 's': NumberOf; + 'n': L['length']; + }[fmt]; + } + declare module "Iteration/Next" { + import { IterationMap } from "Iteration/IterationOf"; + import { Iteration } from "Iteration/Iteration"; + + export type Next = IterationMap[I[1]]; + } + declare module "Any/Cast" { + export type Cast = A1 extends A2 ? A1 : A2; + } + declare module "Function/Parameters" { + import { Function } from "Function/Function"; + + export type Parameters = F extends ((...args: infer L) => any) ? L : never; + } + declare module "Function/Return" { + import { Function } from "Function/Function"; + + export type Return = F extends ((...args: any[]) => infer R) ? R : never; + } + declare module "Iteration/Prev" { + import { IterationMap } from "Iteration/IterationOf"; + import { Iteration } from "Iteration/Iteration"; + + export type Prev = IterationMap[I[0]]; + } + declare module "Number/NumberOf" { + import { IterationMap } from "Iteration/IterationOf"; + import { Key } from "Iteration/Key"; + import { Pos } from "Iteration/Pos"; + import { Numbers } from "Number/_Internal"; + + export type _NumberOf = { + [K in keyof IterationMap]: Pos extends N ? Key : never; + }[keyof IterationMap]; + + export type NumberOf = N extends Numbers['number']['all'] ? _NumberOf : string; + } + declare module "Object/_Internal" { + export type Modx = ['?' | '!', 'W' | 'R']; + + export type Depth = 'flat' | 'deep'; + + export type Empty = { + [K in keyof O]: undefined; + }; + } + declare module "Iteration/IterationOf" { + import { Number } from "Number/Number"; + + export type IterationMap = { + '-40': ['__', '-39', '-40', -40, '-']; + '-39': ['-40', '-38', '-39', -39, '-']; + '-38': ['-39', '-37', '-38', -38, '-']; + '-37': ['-38', '-36', '-37', -37, '-']; + '-36': ['-37', '-35', '-36', -36, '-']; + '-35': ['-36', '-34', '-35', -35, '-']; + '-34': ['-35', '-33', '-34', -34, '-']; + '-33': ['-34', '-32', '-33', -33, '-']; + '-32': ['-33', '-31', '-32', -32, '-']; + '-31': ['-32', '-30', '-31', -31, '-']; + '-30': ['-31', '-29', '-30', -30, '-']; + '-29': ['-30', '-28', '-29', -29, '-']; + '-28': ['-29', '-27', '-28', -28, '-']; + '-27': ['-28', '-26', '-27', -27, '-']; + '-26': ['-27', '-25', '-26', -26, '-']; + '-25': ['-26', '-24', '-25', -25, '-']; + '-24': ['-25', '-23', '-24', -24, '-']; + '-23': ['-24', '-22', '-23', -23, '-']; + '-22': ['-23', '-21', '-22', -22, '-']; + '-21': ['-22', '-20', '-21', -21, '-']; + '-20': ['-21', '-19', '-20', -20, '-']; + '-19': ['-20', '-18', '-19', -19, '-']; + '-18': ['-19', '-17', '-18', -18, '-']; + '-17': ['-18', '-16', '-17', -17, '-']; + '-16': ['-17', '-15', '-16', -16, '-']; + '-15': ['-16', '-14', '-15', -15, '-']; + '-14': ['-15', '-13', '-14', -14, '-']; + '-13': ['-14', '-12', '-13', -13, '-']; + '-12': ['-13', '-11', '-12', -12, '-']; + '-11': ['-12', '-10', '-11', -11, '-']; + '-10': ['-11', '-9', '-10', -10, '-']; + '-9': ['-10', '-8', '-9', -9, '-']; + '-8': ['-9', '-7', '-8', -8, '-']; + '-7': ['-8', '-6', '-7', -7, '-']; + '-6': ['-7', '-5', '-6', -6, '-']; + '-5': ['-6', '-4', '-5', -5, '-']; + '-4': ['-5', '-3', '-4', -4, '-']; + '-3': ['-4', '-2', '-3', -3, '-']; + '-2': ['-3', '-1', '-2', -2, '-']; + '-1': ['-2', '0', '-1', -1, '-']; + '0': ['-1', '1', '0', 0, '0']; + '1': ['0', '2', '1', 1, '+']; + '2': ['1', '3', '2', 2, '+']; + '3': ['2', '4', '3', 3, '+']; + '4': ['3', '5', '4', 4, '+']; + '5': ['4', '6', '5', 5, '+']; + '6': ['5', '7', '6', 6, '+']; + '7': ['6', '8', '7', 7, '+']; + '8': ['7', '9', '8', 8, '+']; + '9': ['8', '10', '9', 9, '+']; + '10': ['9', '11', '10', 10, '+']; + '11': ['10', '12', '11', 11, '+']; + '12': ['11', '13', '12', 12, '+']; + '13': ['12', '14', '13', 13, '+']; + '14': ['13', '15', '14', 14, '+']; + '15': ['14', '16', '15', 15, '+']; + '16': ['15', '17', '16', 16, '+']; + '17': ['16', '18', '17', 17, '+']; + '18': ['17', '19', '18', 18, '+']; + '19': ['18', '20', '19', 19, '+']; + '20': ['19', '21', '20', 20, '+']; + '21': ['20', '22', '21', 21, '+']; + '22': ['21', '23', '22', 22, '+']; + '23': ['22', '24', '23', 23, '+']; + '24': ['23', '25', '24', 24, '+']; + '25': ['24', '26', '25', 25, '+']; + '26': ['25', '27', '26', 26, '+']; + '27': ['26', '28', '27', 27, '+']; + '28': ['27', '29', '28', 28, '+']; + '29': ['28', '30', '29', 29, '+']; + '30': ['29', '31', '30', 30, '+']; + '31': ['30', '32', '31', 31, '+']; + '32': ['31', '33', '32', 32, '+']; + '33': ['32', '34', '33', 33, '+']; + '34': ['33', '35', '34', 34, '+']; + '35': ['34', '36', '35', 35, '+']; + '36': ['35', '37', '36', 36, '+']; + '37': ['36', '38', '37', 37, '+']; + '38': ['37', '39', '38', 38, '+']; + '39': ['38', '40', '39', 39, '+']; + '40': ['39', '__', '40', 40, '+']; + '__': ['__', '__', string, number, '-' | '0' | '+']; + }; + + export type IterationOf = N extends keyof IterationMap ? IterationMap[N] : IterationMap['__']; + } + declare module "Iteration/Iteration" { + import { IterationMap } from "Iteration/IterationOf"; + + export type Iteration = [keyof IterationMap, keyof IterationMap, string, number, '-' | '0' | '+']; + } + declare module "Iteration/Key" { + import { Iteration } from "Iteration/Iteration"; + import { Format } from "Iteration/Format"; + + export type Key = Format; + } + declare module "List/NonNullable" { + import { Depth } from "Object/_Internal"; + import { NonNullable as ONonNullable } from "Object/NonNullable"; + import { ListOf } from "Object/ListOf"; + import { Cast } from "Any/Cast"; + import { Key } from "Any/Key"; + import { ObjectOf } from "List/ObjectOf"; + import { Implements } from "Any/Implements"; + import { Keys } from "List/Keys"; + import { List } from "List/List"; + import { NumberOf } from "Any/_Internal"; + + export type NonNullable = { + 1: Cast, List>; + 0: ListOf, NumberOf, depth>>; + }[Implements, K>] & {}; + } + declare module "Any/Type" { + const symbol: unique symbol; + + export type Type = A & { + [K in typeof symbol]: Id; + }; + } + declare module "Any/x" { + import { Type } from "Any/Type"; + + export type x = Type<{}, 'x'>; + } + declare module "List/List" { + + export type List = ReadonlyArray; + } + declare module "Function/Function" { + import { List } from "List/List"; + + export interface Function

{ + (...args: P): R; + } + } + declare module "Any/Extends" { + export type Extends = [A1] extends [never] ? 0 : A1 extends A2 ? 1 : 0; + } + + declare module "Function/Curry" { + import { Pos } from "Iteration/Pos"; + import { _Append } from "List/Append"; + import { _Concat } from "List/Concat"; + import { _Drop } from "List/Drop"; + import { Length } from "List/Length"; + import { Next } from "Iteration/Next"; + import { Cast } from "Any/Cast"; + import { Parameters } from "Function/Parameters"; + import { Return } from "Function/Return"; + import { IterationOf } from "Iteration/IterationOf"; + import { Iteration } from "Iteration/Iteration"; + import { Key } from "Iteration/Key"; + import { NonNullable } from "List/NonNullable"; + import { x } from "Any/x"; + import { List } from "List/List"; + import { Function } from "Function/Function"; + import { Extends } from "Any/Extends"; + + type GapOf> = L1[Pos] extends x ? _Append]> : LN; + + type _GapsOf> = { + 0: _GapsOf, Next>; + 1: _Concat>>; + }[Extends, Length>]; + + type GapsOf = _GapsOf extends infer X ? Cast : never; + + type Gaps = NonNullable<{ + [K in keyof L]?: L[K] | x; + }>; + + export type Curry = (...args: Cast>>) => GapsOf> extends infer G ? Length> extends infer L ? L extends 0 ? Return : L extends 1 ? Curry<(...args: Cast) => Return> & ((...args: Cast) => Return) : Curry<(...args: Cast) => Return> : never : never; + } + + + \ No newline at end of file diff --git a/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt b/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt index 97847882fb3c8..ce706f7a36f52 100644 --- a/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt +++ b/tests/baselines/reference/spreadOfParamsFromGeneratorMakesRequiredParams.errors.txt @@ -1,8 +1,6 @@ -error TS2318: Cannot find global type 'IterableIterator'. spreadOfParamsFromGeneratorMakesRequiredParams.ts(6,1): error TS2554: Expected 2 arguments, but got 1. -!!! error TS2318: Cannot find global type 'IterableIterator'. ==== spreadOfParamsFromGeneratorMakesRequiredParams.ts (1 errors) ==== declare function call any>( fn: Fn, diff --git a/tests/baselines/reference/targetTypeArgs.types b/tests/baselines/reference/targetTypeArgs.types index 5639356b4cdea..d49040385ad4d 100644 --- a/tests/baselines/reference/targetTypeArgs.types +++ b/tests/baselines/reference/targetTypeArgs.types @@ -37,7 +37,7 @@ foo(function(x) { x }); >["hello"] : string[] >"hello" : "hello" >every : { (predicate: (value: string, index: number, array: string[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any): boolean; } ->function(v,i,a) {return true;} : (v: string, i: number, a: string[]) => true +>function(v,i,a) {return true;} : (v: string, i: number, a: string[]) => boolean >v : string >i : number >a : string[] @@ -49,7 +49,7 @@ foo(function(x) { x }); >[1] : number[] >1 : 1 >every : { (predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; } ->function(v,i,a) {return true;} : (v: number, i: number, a: number[]) => true +>function(v,i,a) {return true;} : (v: number, i: number, a: number[]) => boolean >v : number >i : number >a : number[] @@ -61,7 +61,7 @@ foo(function(x) { x }); >[1] : number[] >1 : 1 >every : { (predicate: (value: number, index: number, array: number[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: number, index: number, array: number[]) => unknown, thisArg?: any): boolean; } ->function(v,i,a) {return true;} : (v: number, i: number, a: number[]) => true +>function(v,i,a) {return true;} : (v: number, i: number, a: number[]) => boolean >v : number >i : number >a : number[] @@ -73,7 +73,7 @@ foo(function(x) { x }); >["s"] : string[] >"s" : "s" >every : { (predicate: (value: string, index: number, array: string[]) => value is S, thisArg?: any): this is S[]; (predicate: (value: string, index: number, array: string[]) => unknown, thisArg?: any): boolean; } ->function(v,i,a) {return true;} : (v: string, i: number, a: string[]) => true +>function(v,i,a) {return true;} : (v: string, i: number, a: string[]) => boolean >v : string >i : number >a : string[] diff --git a/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.errors.txt b/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.errors.txt new file mode 100644 index 0000000000000..6c948133e5b65 --- /dev/null +++ b/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.errors.txt @@ -0,0 +1,24 @@ +thisConditionalOnMethodReturnOfGenericInstance.ts(6,15): error TS2577: Return type annotation circularly references itself. + + +==== thisConditionalOnMethodReturnOfGenericInstance.ts (1 errors) ==== + class A { + unmeasurableUsage!: {[K in keyof T]-?: T[K]}; + } + + class B extends A { + method(): string | (this extends C ? undefined : null) { + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +!!! error TS2577: Return type annotation circularly references itself. + return ""; + } + } + + class C extends B { + marker!: string; + } + + const x = new C<{}>(); + + const y = x.method(); // usage flags `method` in `B` as circular and marks `y` as the error-any type + \ No newline at end of file diff --git a/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.types b/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.types index cad4adc4b4080..657cc953ee246 100644 --- a/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.types +++ b/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.types @@ -34,9 +34,9 @@ const x = new C<{}>(); >C : typeof C const y = x.method(); // usage flags `method` in `B` as circular and marks `y` as the error-any type ->y : string | undefined ->x.method() : string | undefined ->x.method : () => string | undefined +>y : any +>x.method() : any +>x.method : () => any >x : C<{}> ->method : () => string | undefined +>method : () => any diff --git a/tests/baselines/reference/unionOfClassCalls.types b/tests/baselines/reference/unionOfClassCalls.types index c31e22185f9c7..100854b37a1d0 100644 --- a/tests/baselines/reference/unionOfClassCalls.types +++ b/tests/baselines/reference/unionOfClassCalls.types @@ -66,7 +66,7 @@ arr.map((a: number | string, index: number) => { // This case still doesn't work because `reduce` has multiple overloads :( arr.reduce((acc: Array, a: number | string, index: number) => { ->arr.reduce((acc: Array, a: number | string, index: number) => { return []}, []) : never[] +>arr.reduce((acc: Array, a: number | string, index: number) => { return []}, []) : string[] >arr.reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } | { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U_1, currentValue: string, currentIndex: number, array: string[]) => U_1, initialValue: U_1): U_1; } >arr : number[] | string[] >reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } | { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U_1, currentValue: string, currentIndex: number, array: string[]) => U_1, initialValue: U_1): U_1; } @@ -154,7 +154,7 @@ arr2.map((a: string, index: number) => { }) arr2.reduce((acc: string[], a: string, index: number) => { ->arr2.reduce((acc: string[], a: string, index: number) => { return []}, []) : never[] +>arr2.reduce((acc: string[], a: string, index: number) => { return []}, []) : string[] >arr2.reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } >arr2 : string[] >reduce : { (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string): string; (callbackfn: (previousValue: string, currentValue: string, currentIndex: number, array: string[]) => string, initialValue: string): string; (callbackfn: (previousValue: U, currentValue: string, currentIndex: number, array: string[]) => U, initialValue: U): U; } From d258aa37803edd9782ed591616f0483410bbf259 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 15 Feb 2024 13:43:20 -0800 Subject: [PATCH 04/18] Add extra tests --- ...nNoInferenceLeaksBetweenFailedOverloads.js | 73 ++++++ ...ferenceLeaksBetweenFailedOverloads.symbols | 210 ++++++++++++++++ ...InferenceLeaksBetweenFailedOverloads.types | 233 ++++++++++++++++++ ...nNoInferenceLeaksBetweenFailedOverloads.ts | 48 ++++ 4 files changed, 564 insertions(+) create mode 100644 tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.js create mode 100644 tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.symbols create mode 100644 tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.types create mode 100644 tests/cases/compiler/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.ts diff --git a/tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.js b/tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.js new file mode 100644 index 0000000000000..48d4dd0355657 --- /dev/null +++ b/tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.js @@ -0,0 +1,73 @@ +//// [tests/cases/compiler/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.ts] //// + +//// [49820.ts] +type A1 = { type: "a1", v: T }; +type B1 = { type: "b1", v: T }; +type A2 = { a2: string }; +type B2 = { b2: string }; + +function fn(p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; +function fn(p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; +function fn( + p1: + | ((pp1: 0) => A1) + | ((pp1: 0) => B1), + p2: + | ((pp2: A2) => 0) + | ((pp2: B2) => 0) +) {} + +const valA1: A1 = ({ type: "a1", v: "" }); +const valB1: B1 = ({ type: "b1", v: "" }); + +// expect A +fn((ap1) => valA1, (ap2) => 0); +fn((ap1) => valA1, (ap2: A2) => 0); +fn((ap1) => valA1, (ap2: any) => 0); +fn((ap1) => valA1, (ap2: unknown) => 0); +fn((ap1: 0) => valA1, (ap2) => 0); +// expect B +fn((bp1) => valB1, (bp2) => 0); // but it will be A, only this will result in an error +fn((bp1) => valB1, (bp2: B2) => 0); +fn((bp1) => valB1, (bp2: any) => 0); +fn((bp1) => valB1, (bp2: unknown) => 0); +fn((bp1: 0) => valB1, (bp2) => 0); +//// [13430.ts] +declare function it(f: () => void): number; +declare function it(f: (x: string) => void): string; + +let r = it((x) => {x}); +//// [21525.ts] +interface TestFunction { + (input: { [key: number]: T }, callback: (value: T, key: number, collection: { [key: number]: T }) => boolean): boolean; + (input: T, callback: (value: T[keyof T], key: string, collection: T) => boolean): boolean; +} + +const fn: TestFunction = {} as any; +fn({ a: "a", b: "b" }, (value, key) => true); + + +//// [49820.js] +function fn(p1, p2) { } +const valA1 = ({ type: "a1", v: "" }); +const valB1 = ({ type: "b1", v: "" }); +// expect A +fn((ap1) => valA1, (ap2) => 0); +fn((ap1) => valA1, (ap2) => 0); +fn((ap1) => valA1, (ap2) => 0); +fn((ap1) => valA1, (ap2) => 0); +fn((ap1) => valA1, (ap2) => 0); +// expect B +fn((bp1) => valB1, (bp2) => 0); // but it will be A, only this will result in an error +fn((bp1) => valB1, (bp2) => 0); +fn((bp1) => valB1, (bp2) => 0); +fn((bp1) => valB1, (bp2) => 0); +fn((bp1) => valB1, (bp2) => 0); +export {}; +//// [13430.js] +let r = it((x) => { x; }); +export {}; +//// [21525.js] +const fn = {}; +fn({ a: "a", b: "b" }, (value, key) => true); +export {}; diff --git a/tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.symbols b/tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.symbols new file mode 100644 index 0000000000000..2d0877bc2e2c4 --- /dev/null +++ b/tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.symbols @@ -0,0 +1,210 @@ +//// [tests/cases/compiler/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.ts] //// + +=== 49820.ts === +type A1 = { type: "a1", v: T }; +>A1 : Symbol(A1, Decl(49820.ts, 0, 0)) +>T : Symbol(T, Decl(49820.ts, 0, 8)) +>type : Symbol(type, Decl(49820.ts, 0, 14)) +>v : Symbol(v, Decl(49820.ts, 0, 26)) +>T : Symbol(T, Decl(49820.ts, 0, 8)) + +type B1 = { type: "b1", v: T }; +>B1 : Symbol(B1, Decl(49820.ts, 0, 34)) +>T : Symbol(T, Decl(49820.ts, 1, 8)) +>type : Symbol(type, Decl(49820.ts, 1, 14)) +>v : Symbol(v, Decl(49820.ts, 1, 26)) +>T : Symbol(T, Decl(49820.ts, 1, 8)) + +type A2 = { a2: string }; +>A2 : Symbol(A2, Decl(49820.ts, 1, 34)) +>a2 : Symbol(a2, Decl(49820.ts, 2, 11)) + +type B2 = { b2: string }; +>B2 : Symbol(B2, Decl(49820.ts, 2, 25)) +>b2 : Symbol(b2, Decl(49820.ts, 3, 11)) + +function fn(p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>T : Symbol(T, Decl(49820.ts, 5, 12)) +>p1 : Symbol(p1, Decl(49820.ts, 5, 15)) +>pp1 : Symbol(pp1, Decl(49820.ts, 5, 20)) +>A1 : Symbol(A1, Decl(49820.ts, 0, 0)) +>T : Symbol(T, Decl(49820.ts, 5, 12)) +>p2 : Symbol(p2, Decl(49820.ts, 5, 37)) +>pp2 : Symbol(pp2, Decl(49820.ts, 5, 43)) +>A2 : Symbol(A2, Decl(49820.ts, 1, 34)) + +function fn(p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>T : Symbol(T, Decl(49820.ts, 6, 12)) +>p1 : Symbol(p1, Decl(49820.ts, 6, 15)) +>pp1 : Symbol(pp1, Decl(49820.ts, 6, 20)) +>B1 : Symbol(B1, Decl(49820.ts, 0, 34)) +>T : Symbol(T, Decl(49820.ts, 6, 12)) +>p2 : Symbol(p2, Decl(49820.ts, 6, 37)) +>pp2 : Symbol(pp2, Decl(49820.ts, 6, 43)) +>B2 : Symbol(B2, Decl(49820.ts, 2, 25)) + +function fn( +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>T : Symbol(T, Decl(49820.ts, 7, 12)) + + p1: +>p1 : Symbol(p1, Decl(49820.ts, 7, 15)) + + | ((pp1: 0) => A1) +>pp1 : Symbol(pp1, Decl(49820.ts, 9, 8)) +>A1 : Symbol(A1, Decl(49820.ts, 0, 0)) +>T : Symbol(T, Decl(49820.ts, 7, 12)) + + | ((pp1: 0) => B1), +>pp1 : Symbol(pp1, Decl(49820.ts, 10, 8)) +>B1 : Symbol(B1, Decl(49820.ts, 0, 34)) +>T : Symbol(T, Decl(49820.ts, 7, 12)) + + p2: +>p2 : Symbol(p2, Decl(49820.ts, 10, 26)) + + | ((pp2: A2) => 0) +>pp2 : Symbol(pp2, Decl(49820.ts, 12, 8)) +>A2 : Symbol(A2, Decl(49820.ts, 1, 34)) + + | ((pp2: B2) => 0) +>pp2 : Symbol(pp2, Decl(49820.ts, 13, 8)) +>B2 : Symbol(B2, Decl(49820.ts, 2, 25)) + +) {} + +const valA1: A1 = ({ type: "a1", v: "" }); +>valA1 : Symbol(valA1, Decl(49820.ts, 16, 5)) +>A1 : Symbol(A1, Decl(49820.ts, 0, 0)) +>type : Symbol(type, Decl(49820.ts, 16, 28)) +>v : Symbol(v, Decl(49820.ts, 16, 40)) + +const valB1: B1 = ({ type: "b1", v: "" }); +>valB1 : Symbol(valB1, Decl(49820.ts, 17, 5)) +>B1 : Symbol(B1, Decl(49820.ts, 0, 34)) +>type : Symbol(type, Decl(49820.ts, 17, 28)) +>v : Symbol(v, Decl(49820.ts, 17, 40)) + +// expect A +fn((ap1) => valA1, (ap2) => 0); +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>ap1 : Symbol(ap1, Decl(49820.ts, 20, 4)) +>valA1 : Symbol(valA1, Decl(49820.ts, 16, 5)) +>ap2 : Symbol(ap2, Decl(49820.ts, 20, 20)) + +fn((ap1) => valA1, (ap2: A2) => 0); +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>ap1 : Symbol(ap1, Decl(49820.ts, 21, 4)) +>valA1 : Symbol(valA1, Decl(49820.ts, 16, 5)) +>ap2 : Symbol(ap2, Decl(49820.ts, 21, 20)) +>A2 : Symbol(A2, Decl(49820.ts, 1, 34)) + +fn((ap1) => valA1, (ap2: any) => 0); +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>ap1 : Symbol(ap1, Decl(49820.ts, 22, 4)) +>valA1 : Symbol(valA1, Decl(49820.ts, 16, 5)) +>ap2 : Symbol(ap2, Decl(49820.ts, 22, 20)) + +fn((ap1) => valA1, (ap2: unknown) => 0); +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>ap1 : Symbol(ap1, Decl(49820.ts, 23, 4)) +>valA1 : Symbol(valA1, Decl(49820.ts, 16, 5)) +>ap2 : Symbol(ap2, Decl(49820.ts, 23, 20)) + +fn((ap1: 0) => valA1, (ap2) => 0); +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>ap1 : Symbol(ap1, Decl(49820.ts, 24, 4)) +>valA1 : Symbol(valA1, Decl(49820.ts, 16, 5)) +>ap2 : Symbol(ap2, Decl(49820.ts, 24, 23)) + +// expect B +fn((bp1) => valB1, (bp2) => 0); // but it will be A, only this will result in an error +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>bp1 : Symbol(bp1, Decl(49820.ts, 26, 4)) +>valB1 : Symbol(valB1, Decl(49820.ts, 17, 5)) +>bp2 : Symbol(bp2, Decl(49820.ts, 26, 20)) + +fn((bp1) => valB1, (bp2: B2) => 0); +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>bp1 : Symbol(bp1, Decl(49820.ts, 27, 4)) +>valB1 : Symbol(valB1, Decl(49820.ts, 17, 5)) +>bp2 : Symbol(bp2, Decl(49820.ts, 27, 20)) +>B2 : Symbol(B2, Decl(49820.ts, 2, 25)) + +fn((bp1) => valB1, (bp2: any) => 0); +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>bp1 : Symbol(bp1, Decl(49820.ts, 28, 4)) +>valB1 : Symbol(valB1, Decl(49820.ts, 17, 5)) +>bp2 : Symbol(bp2, Decl(49820.ts, 28, 20)) + +fn((bp1) => valB1, (bp2: unknown) => 0); +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>bp1 : Symbol(bp1, Decl(49820.ts, 29, 4)) +>valB1 : Symbol(valB1, Decl(49820.ts, 17, 5)) +>bp2 : Symbol(bp2, Decl(49820.ts, 29, 20)) + +fn((bp1: 0) => valB1, (bp2) => 0); +>fn : Symbol(fn, Decl(49820.ts, 3, 25), Decl(49820.ts, 5, 64), Decl(49820.ts, 6, 64)) +>bp1 : Symbol(bp1, Decl(49820.ts, 30, 4)) +>valB1 : Symbol(valB1, Decl(49820.ts, 17, 5)) +>bp2 : Symbol(bp2, Decl(49820.ts, 30, 23)) + +=== 13430.ts === +declare function it(f: () => void): number; +>it : Symbol(it, Decl(13430.ts, 0, 0), Decl(13430.ts, 0, 43)) +>f : Symbol(f, Decl(13430.ts, 0, 20)) + +declare function it(f: (x: string) => void): string; +>it : Symbol(it, Decl(13430.ts, 0, 0), Decl(13430.ts, 0, 43)) +>f : Symbol(f, Decl(13430.ts, 1, 20)) +>x : Symbol(x, Decl(13430.ts, 1, 24)) + +let r = it((x) => {x}); +>r : Symbol(r, Decl(13430.ts, 3, 3)) +>it : Symbol(it, Decl(13430.ts, 0, 0), Decl(13430.ts, 0, 43)) +>x : Symbol(x, Decl(13430.ts, 3, 12)) +>x : Symbol(x, Decl(13430.ts, 3, 12)) + +=== 21525.ts === +interface TestFunction { +>TestFunction : Symbol(TestFunction, Decl(21525.ts, 0, 0)) + + (input: { [key: number]: T }, callback: (value: T, key: number, collection: { [key: number]: T }) => boolean): boolean; +>T : Symbol(T, Decl(21525.ts, 1, 5)) +>input : Symbol(input, Decl(21525.ts, 1, 8)) +>key : Symbol(key, Decl(21525.ts, 1, 18)) +>T : Symbol(T, Decl(21525.ts, 1, 5)) +>callback : Symbol(callback, Decl(21525.ts, 1, 36)) +>value : Symbol(value, Decl(21525.ts, 1, 48)) +>T : Symbol(T, Decl(21525.ts, 1, 5)) +>key : Symbol(key, Decl(21525.ts, 1, 57)) +>collection : Symbol(collection, Decl(21525.ts, 1, 70)) +>key : Symbol(key, Decl(21525.ts, 1, 86)) +>T : Symbol(T, Decl(21525.ts, 1, 5)) + + (input: T, callback: (value: T[keyof T], key: string, collection: T) => boolean): boolean; +>T : Symbol(T, Decl(21525.ts, 2, 5)) +>input : Symbol(input, Decl(21525.ts, 2, 23)) +>T : Symbol(T, Decl(21525.ts, 2, 5)) +>callback : Symbol(callback, Decl(21525.ts, 2, 32)) +>value : Symbol(value, Decl(21525.ts, 2, 44)) +>T : Symbol(T, Decl(21525.ts, 2, 5)) +>T : Symbol(T, Decl(21525.ts, 2, 5)) +>key : Symbol(key, Decl(21525.ts, 2, 62)) +>collection : Symbol(collection, Decl(21525.ts, 2, 75)) +>T : Symbol(T, Decl(21525.ts, 2, 5)) +} + +const fn: TestFunction = {} as any; +>fn : Symbol(fn, Decl(21525.ts, 5, 5)) +>TestFunction : Symbol(TestFunction, Decl(21525.ts, 0, 0)) + +fn({ a: "a", b: "b" }, (value, key) => true); +>fn : Symbol(fn, Decl(21525.ts, 5, 5)) +>a : Symbol(a, Decl(21525.ts, 6, 4)) +>b : Symbol(b, Decl(21525.ts, 6, 12)) +>value : Symbol(value, Decl(21525.ts, 6, 24)) +>key : Symbol(key, Decl(21525.ts, 6, 30)) + diff --git a/tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.types b/tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.types new file mode 100644 index 0000000000000..0e0ccc41dfe5f --- /dev/null +++ b/tests/baselines/reference/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.types @@ -0,0 +1,233 @@ +//// [tests/cases/compiler/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.ts] //// + +=== 49820.ts === +type A1 = { type: "a1", v: T }; +>A1 : A1 +>type : "a1" +>v : T + +type B1 = { type: "b1", v: T }; +>B1 : B1 +>type : "b1" +>v : T + +type A2 = { a2: string }; +>A2 : { a2: string; } +>a2 : string + +type B2 = { b2: string }; +>B2 : { b2: string; } +>b2 : string + +function fn(p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>p1 : (pp1: 0) => A1 +>pp1 : 0 +>p2 : (pp2: A2) => 0 +>pp2 : A2 + +function fn(p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>p1 : (pp1: 0) => B1 +>pp1 : 0 +>p2 : (pp2: B2) => 0 +>pp2 : B2 + +function fn( +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } + + p1: +>p1 : ((pp1: 0) => A1) | ((pp1: 0) => B1) + + | ((pp1: 0) => A1) +>pp1 : 0 + + | ((pp1: 0) => B1), +>pp1 : 0 + + p2: +>p2 : ((pp2: A2) => 0) | ((pp2: B2) => 0) + + | ((pp2: A2) => 0) +>pp2 : A2 + + | ((pp2: B2) => 0) +>pp2 : B2 + +) {} + +const valA1: A1 = ({ type: "a1", v: "" }); +>valA1 : A1 +>({ type: "a1", v: "" }) : { type: "a1"; v: string; } +>{ type: "a1", v: "" } : { type: "a1"; v: string; } +>type : "a1" +>"a1" : "a1" +>v : string +>"" : "" + +const valB1: B1 = ({ type: "b1", v: "" }); +>valB1 : B1 +>({ type: "b1", v: "" }) : { type: "b1"; v: string; } +>{ type: "b1", v: "" } : { type: "b1"; v: string; } +>type : "b1" +>"b1" : "b1" +>v : string +>"" : "" + +// expect A +fn((ap1) => valA1, (ap2) => 0); +>fn((ap1) => valA1, (ap2) => 0) : void +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>(ap1) => valA1 : (ap1: 0) => A1 +>ap1 : 0 +>valA1 : A1 +>(ap2) => 0 : (ap2: A2) => 0 +>ap2 : A2 +>0 : 0 + +fn((ap1) => valA1, (ap2: A2) => 0); +>fn((ap1) => valA1, (ap2: A2) => 0) : void +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>(ap1) => valA1 : (ap1: 0) => A1 +>ap1 : 0 +>valA1 : A1 +>(ap2: A2) => 0 : (ap2: A2) => 0 +>ap2 : A2 +>0 : 0 + +fn((ap1) => valA1, (ap2: any) => 0); +>fn((ap1) => valA1, (ap2: any) => 0) : void +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>(ap1) => valA1 : (ap1: 0) => A1 +>ap1 : 0 +>valA1 : A1 +>(ap2: any) => 0 : (ap2: any) => 0 +>ap2 : any +>0 : 0 + +fn((ap1) => valA1, (ap2: unknown) => 0); +>fn((ap1) => valA1, (ap2: unknown) => 0) : void +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>(ap1) => valA1 : (ap1: 0) => A1 +>ap1 : 0 +>valA1 : A1 +>(ap2: unknown) => 0 : (ap2: unknown) => 0 +>ap2 : unknown +>0 : 0 + +fn((ap1: 0) => valA1, (ap2) => 0); +>fn((ap1: 0) => valA1, (ap2) => 0) : void +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>(ap1: 0) => valA1 : (ap1: 0) => A1 +>ap1 : 0 +>valA1 : A1 +>(ap2) => 0 : (ap2: A2) => 0 +>ap2 : A2 +>0 : 0 + +// expect B +fn((bp1) => valB1, (bp2) => 0); // but it will be A, only this will result in an error +>fn((bp1) => valB1, (bp2) => 0) : void +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>(bp1) => valB1 : (bp1: 0) => B1 +>bp1 : 0 +>valB1 : B1 +>(bp2) => 0 : (bp2: B2) => 0 +>bp2 : B2 +>0 : 0 + +fn((bp1) => valB1, (bp2: B2) => 0); +>fn((bp1) => valB1, (bp2: B2) => 0) : void +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>(bp1) => valB1 : (bp1: 0) => B1 +>bp1 : 0 +>valB1 : B1 +>(bp2: B2) => 0 : (bp2: B2) => 0 +>bp2 : B2 +>0 : 0 + +fn((bp1) => valB1, (bp2: any) => 0); +>fn((bp1) => valB1, (bp2: any) => 0) : void +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>(bp1) => valB1 : (bp1: 0) => B1 +>bp1 : 0 +>valB1 : B1 +>(bp2: any) => 0 : (bp2: any) => 0 +>bp2 : any +>0 : 0 + +fn((bp1) => valB1, (bp2: unknown) => 0); +>fn((bp1) => valB1, (bp2: unknown) => 0) : void +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>(bp1) => valB1 : (bp1: 0) => B1 +>bp1 : 0 +>valB1 : B1 +>(bp2: unknown) => 0 : (bp2: unknown) => 0 +>bp2 : unknown +>0 : 0 + +fn((bp1: 0) => valB1, (bp2) => 0); +>fn((bp1: 0) => valB1, (bp2) => 0) : void +>fn : { (p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; (p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; } +>(bp1: 0) => valB1 : (bp1: 0) => B1 +>bp1 : 0 +>valB1 : B1 +>(bp2) => 0 : (bp2: B2) => 0 +>bp2 : B2 +>0 : 0 + +=== 13430.ts === +declare function it(f: () => void): number; +>it : { (f: () => void): number; (f: (x: string) => void): string; } +>f : () => void + +declare function it(f: (x: string) => void): string; +>it : { (f: () => void): number; (f: (x: string) => void): string; } +>f : (x: string) => void +>x : string + +let r = it((x) => {x}); +>r : string +>it((x) => {x}) : string +>it : { (f: () => void): number; (f: (x: string) => void): string; } +>(x) => {x} : (x: string) => void +>x : string +>x : string + +=== 21525.ts === +interface TestFunction { + (input: { [key: number]: T }, callback: (value: T, key: number, collection: { [key: number]: T }) => boolean): boolean; +>input : { [key: number]: T; } +>key : number +>callback : (value: T, key: number, collection: { [key: number]: T; }) => boolean +>value : T +>key : number +>collection : { [key: number]: T; } +>key : number + + (input: T, callback: (value: T[keyof T], key: string, collection: T) => boolean): boolean; +>input : T +>callback : (value: T[keyof T], key: string, collection: T) => boolean +>value : T[keyof T] +>key : string +>collection : T +} + +const fn: TestFunction = {} as any; +>fn : TestFunction +>{} as any : any +>{} : {} + +fn({ a: "a", b: "b" }, (value, key) => true); +>fn({ a: "a", b: "b" }, (value, key) => true) : boolean +>fn : TestFunction +>{ a: "a", b: "b" } : { a: string; b: string; } +>a : string +>"a" : "a" +>b : string +>"b" : "b" +>(value, key) => true : (value: string, key: string) => true +>value : string +>key : string +>true : true + diff --git a/tests/cases/compiler/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.ts b/tests/cases/compiler/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.ts new file mode 100644 index 0000000000000..31bd696ea8320 --- /dev/null +++ b/tests/cases/compiler/overloadResolutionNoInferenceLeaksBetweenFailedOverloads.ts @@ -0,0 +1,48 @@ +// @strict: true +// @target: es2020 +// @moduleDetection: force +// @filename: 49820.ts +type A1 = { type: "a1", v: T }; +type B1 = { type: "b1", v: T }; +type A2 = { a2: string }; +type B2 = { b2: string }; + +function fn(p1: (pp1: 0) => A1, p2: (pp2: A2) => 0): void; +function fn(p1: (pp1: 0) => B1, p2: (pp2: B2) => 0): void; +function fn( + p1: + | ((pp1: 0) => A1) + | ((pp1: 0) => B1), + p2: + | ((pp2: A2) => 0) + | ((pp2: B2) => 0) +) {} + +const valA1: A1 = ({ type: "a1", v: "" }); +const valB1: B1 = ({ type: "b1", v: "" }); + +// expect A +fn((ap1) => valA1, (ap2) => 0); +fn((ap1) => valA1, (ap2: A2) => 0); +fn((ap1) => valA1, (ap2: any) => 0); +fn((ap1) => valA1, (ap2: unknown) => 0); +fn((ap1: 0) => valA1, (ap2) => 0); +// expect B +fn((bp1) => valB1, (bp2) => 0); // but it will be A, only this will result in an error +fn((bp1) => valB1, (bp2: B2) => 0); +fn((bp1) => valB1, (bp2: any) => 0); +fn((bp1) => valB1, (bp2: unknown) => 0); +fn((bp1: 0) => valB1, (bp2) => 0); +// @filename: 13430.ts +declare function it(f: () => void): number; +declare function it(f: (x: string) => void): string; + +let r = it((x) => {x}); +// @filename: 21525.ts +interface TestFunction { + (input: { [key: number]: T }, callback: (value: T, key: number, collection: { [key: number]: T }) => boolean): boolean; + (input: T, callback: (value: T[keyof T], key: string, collection: T) => boolean): boolean; +} + +const fn: TestFunction = {} as any; +fn({ a: "a", b: "b" }, (value, key) => true); From fbf8ffeb28f4b0936be1980071b89c6accb5727c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 15 Feb 2024 14:02:19 -0800 Subject: [PATCH 05/18] Remove unneeded speculative cache registrations --- src/compiler/checker.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 98b74f5d61104..ab451102e1c2d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2272,7 +2272,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var enumNumberIndexInfo = createIndexInfo(numberType, stringType, /*isReadonly*/ true); - var iterationTypesCache = registerSpeculativeCache(new Map()); // cache for common IterationTypes instances + var iterationTypesCache = new Map(); // cache for common IterationTypes instances var noIterationTypes: IterationTypes = { get yieldType(): Type { return Debug.fail("Not supported"); @@ -2330,7 +2330,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } /** Key is "/path/to/a.ts|/path/to/b.ts". */ var amalgamatedDuplicates: Map | undefined; - var reverseMappedCache = registerSpeculativeCache(new Map()); + var reverseMappedCache = new Map(); var homomorphicMappedTypeInferenceStack: string[] = []; var ambientModulesCache: Symbol[] | undefined; /** From d75610cb00c3f4af3676807c7319de288ed63dda Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 15 Feb 2024 14:06:53 -0800 Subject: [PATCH 06/18] Revert removal of circularity error bypass --- src/compiler/checker.ts | 19 +++++++++------ ...OnMethodReturnOfGenericInstance.errors.txt | 24 ------------------- ...ionalOnMethodReturnOfGenericInstance.types | 8 +++---- 3 files changed, 16 insertions(+), 35 deletions(-) delete mode 100644 tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.errors.txt diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ab451102e1c2d..3dca0a2838749 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21080,6 +21080,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } if (!(checkMode & SignatureCheckMode.IgnoreReturnTypes)) { + // If a signature resolution is already in-flight, skip issuing a circularity error + // here and just use the `any` type directly + const targetReturnType = isResolvingReturnTypeOfSignature(target) ? anyType + : target.declaration && isJSConstructor(target.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(target.declaration.symbol)) + : getReturnTypeOfSignature(target); + if (targetReturnType === voidType || targetReturnType === anyType) { + return result; + } + const sourceReturnType = isResolvingReturnTypeOfSignature(source) ? anyType + : source.declaration && isJSConstructor(source.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(source.declaration.symbol)) + : getReturnTypeOfSignature(source); + // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions const targetTypePredicate = getTypePredicateOfSignature(target); if (targetTypePredicate) { @@ -21095,13 +21107,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } } else { - const targetReturnType = target.declaration && isJSConstructor(target.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(target.declaration.symbol)) - : getReturnTypeOfSignature(target); - if (targetReturnType === voidType || targetReturnType === anyType) { - return result; - } - const sourceReturnType = source.declaration && isJSConstructor(source.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(source.declaration.symbol)) - : getReturnTypeOfSignature(source); // When relating callback signatures, we still need to relate return types bi-variantly as otherwise // the containing type wouldn't be co-variant. For example, interface Foo { add(cb: () => T): void } // wouldn't be co-variant for T without this rule. diff --git a/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.errors.txt b/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.errors.txt deleted file mode 100644 index 6c948133e5b65..0000000000000 --- a/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.errors.txt +++ /dev/null @@ -1,24 +0,0 @@ -thisConditionalOnMethodReturnOfGenericInstance.ts(6,15): error TS2577: Return type annotation circularly references itself. - - -==== thisConditionalOnMethodReturnOfGenericInstance.ts (1 errors) ==== - class A { - unmeasurableUsage!: {[K in keyof T]-?: T[K]}; - } - - class B extends A { - method(): string | (this extends C ? undefined : null) { - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2577: Return type annotation circularly references itself. - return ""; - } - } - - class C extends B { - marker!: string; - } - - const x = new C<{}>(); - - const y = x.method(); // usage flags `method` in `B` as circular and marks `y` as the error-any type - \ No newline at end of file diff --git a/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.types b/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.types index 657cc953ee246..cad4adc4b4080 100644 --- a/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.types +++ b/tests/baselines/reference/thisConditionalOnMethodReturnOfGenericInstance.types @@ -34,9 +34,9 @@ const x = new C<{}>(); >C : typeof C const y = x.method(); // usage flags `method` in `B` as circular and marks `y` as the error-any type ->y : any ->x.method() : any ->x.method : () => any +>y : string | undefined +>x.method() : string | undefined +>x.method : () => string | undefined >x : C<{}> ->method : () => any +>method : () => string | undefined From 56a2026779bfbfce2c0777a4284853c4ae21ff4e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 15 Feb 2024 14:36:36 -0800 Subject: [PATCH 07/18] Dont assume deferred type reference target types are resolved when we have an instance (the node state may have been rewound) --- 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 3dca0a2838749..4ae07d1425e62 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -19834,7 +19834,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { type.objectFlags & ObjectFlags.InstantiationExpressionType ? (type as InstantiationExpressionType).node : type.symbol.declarations![0]; const links = getNodeLinks(declaration); - const target = type.objectFlags & ObjectFlags.Reference ? links.resolvedType! as DeferredTypeReference : + const target = type.objectFlags & ObjectFlags.Reference ? getTypeFromTypeNode(declaration as TupleTypeNode | ArrayTypeNode) as DeferredTypeReference : type.objectFlags & ObjectFlags.Instantiated ? type.target! : type; let typeParameters = links.outerTypeParameters; if (!typeParameters) { From 6d0dfbb21f34e3961b77f1d4d070285c44bc99b7 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 15 Feb 2024 14:43:58 -0800 Subject: [PATCH 08/18] Remove whitespace --- 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 4ae07d1425e62..92356c4be863d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -21091,7 +21091,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const sourceReturnType = isResolvingReturnTypeOfSignature(source) ? anyType : source.declaration && isJSConstructor(source.declaration) ? getDeclaredTypeOfClassOrInterface(getMergedSymbol(source.declaration.symbol)) : getReturnTypeOfSignature(source); - + // The following block preserves behavior forbidding boolean returning functions from being assignable to type guard returning functions const targetTypePredicate = getTypePredicateOfSignature(target); if (targetTypePredicate) { From 8a6670975705fbec69ce4b5ddec8a2f5ea8aa0bf Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Fri, 16 Feb 2024 16:36:21 -0800 Subject: [PATCH 09/18] Swap to lazy decorator+accessor-backed speculation machinery for links, fixes timeout locally at least --- src/compiler/checker.ts | 494 +++++++++++++++++----------- src/tsconfig-base.json | 1 + tests/cases/compiler/APILibCheck.ts | 1 + 3 files changed, 296 insertions(+), 200 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 92356c4be863d..ac923c187ef74 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -874,7 +874,6 @@ import { NodeWithTypeArguments, NonNullChain, NonNullExpression, - noop, not, noTruncationMaximumTruncationLength, NumberLiteralType, @@ -1375,45 +1374,97 @@ const intrinsicTypeKinds: ReadonlyMap = new Map(Objec })); /** @internal */ -export class SaveableLinks { - /** - * Static list of fields which should be reset when state is rewound - - * meaning their data is not cached across speculation boundaries. - * - * TODO: This would be better tracked with decorators. - */ - static speculativeCaches = new Set(); - declare ["constructor"]: typeof SaveableLinks; - save(): Partial { - // TODO: Optimize perf to delay copies until necessary, and to copy only changes. - // TODO: Some nested deep caches like `specifierCache` or more meaningfully - // `extendedContainersByFile` should really be deep copied/restored, since they may reference - // Symbol information for discarded speculative symbols. - // TODO: The return type is a `this`, which is an abuse of the type system - const res = {} as Partial; - for (const k of this.constructor.speculativeCaches) { - res[k as keyof this] = this[k as keyof this]; +export interface SpeculationHost { + getCurrentSpeculativeEpoch(): number; + getDiscardedSpeculativeEpochs(): Set; +} + +/** + * Marks an auto accessor as a cache whose value can be rewound by the checker speculation helper. + * + * This is implemented by keeping a record of the speculative "epoch" writes are performed at, and + * returning the result for the highest epoch that hasn't (yet) been marked as "discarded". + * Values stored in discarded epochs are lazily discarded when a read is later performed. + * + * This is designed to be compatible with both `experimentalDecorators` and the final decorators spec, + * so it can be used both in downlevel targets and natively. + */ +const SpeculatableCache = ( + valueOrTarget: ClassAccessorDecoratorTarget | any, + _contextOrPropertyKey: ClassAccessorDecoratorContext | string, + descriptor?: PropertyDescriptor +): /*ClassAccessorDecoratorResult | void*/ any => { + + const baseGet = (descriptor ? descriptor.get! : (valueOrTarget as ClassAccessorDecoratorTarget).get) as (this: T) => V; + const baseSet = (descriptor ? descriptor.set! : (valueOrTarget as ClassAccessorDecoratorTarget).set) as (this: T, v: V) => V; + + return { + ...descriptor, + get: readValue, + set: setValue, + init(this: T, v: V) { + const epoch = this.host.getCurrentSpeculativeEpoch(); + // This array is going to end up sparse, but may at least start dense for high traffic caches + const values: V[] = []; + const writtenEpochs: number[] = [epoch]; + values[epoch] = v; + return { + values, + writtenEpochs + }; } - return res; - } - restore>(state: T | undefined) { - if (state) { - for (const k in state) { - if (!this.constructor.speculativeCaches.has(k)) continue; - if (Object.prototype.hasOwnProperty.call(state, k)) { - this[k as keyof this] = state[k] as unknown as this[keyof this]; - } + }; + + function readValue(this: T) { + const internals = baseGet.call(this); + if (!internals) { return undefined! } + const { + values, + writtenEpochs + } = internals; + + const discardedSpeculativeEpochs = this.host.getDiscardedSpeculativeEpochs(); + + // When the epoch a symbol was made in is discarded, it no longer participates in speculative caching + // if it is kept around. This is a failsafe - ideally transient symbols which are made in a speculative + // context shouldn't escape it - but some may be inserted into non-speculative caches and kept around. + // Ideally, these locations should also become speculatable caches to avoid data leakage between speculative + // contexts. + const hostEpoch = this instanceof SymbolLinks ? this.symbolEpoch : 0; + const symbolDiscarded = discardedSpeculativeEpochs.has(hostEpoch); + + for (let i = writtenEpochs.length - 1; i >= 0; i--) { + if (!symbolDiscarded && discardedSpeculativeEpochs.has(writtenEpochs[i])) { + // by discarding epochs on read like this, we make consecutive reads (very common) + // shortcut to basically an indirect lookup. + delete values[writtenEpochs[i]]; + writtenEpochs.splice(i, 1); + continue; } + return values[writtenEpochs[i]]; } - for (const k in this) { - if (!this.constructor.speculativeCaches.has(k)) continue; - if (!state || !Object.prototype.hasOwnProperty.call(state, k)) { - // TODO: `delete` has perf implications, but we really do want to *remove* the keys we added - // Still, `= undefined` might make future copies unnecessarily heavier, but should otherwise be fine. - // Should choose between them based on perf testing. - this[k] = undefined!; - } + return undefined!; + } + + function setValue(this: T, value: V | undefined) { + const internals = baseGet.call(this); + const currentSpeculativeEpoch = this.host.getCurrentSpeculativeEpoch(); + if (!internals) { + const values = []; + const writtenEpochs = []; + writtenEpochs.push(currentSpeculativeEpoch); + values[currentSpeculativeEpoch] = value!; + baseSet.call(this, { values, writtenEpochs }); + return value!; } + const { + values, + writtenEpochs + } = internals; + writtenEpochs.push(currentSpeculativeEpoch); + // Store the new value at the desired speculative depth + values[currentSpeculativeEpoch] = value!; + return value!; } } @@ -1423,59 +1474,117 @@ export const enum EnumKind { Literal, // Literal enum (each member has a TypeFlags.EnumLiteral type) } + +/** @internal */ +export class SpeculatableLinks { + constructor(public host: SpeculationHost) {} +} + // dprint-ignore /** @internal */ -export class SymbolLinks extends SaveableLinks { - declare _symbolLinksBrand: any; - declare immediateTarget?: Symbol; // Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead. - declare aliasTarget?: Symbol; // Resolved (non-alias) target of an alias - declare target?: Symbol; // Original version of an instantiated symbol - declare type?: Type; // Type of value symbol - declare writeType?: Type; // Type of value symbol in write contexts - declare nameType?: Type; // Type associated with a late-bound symbol - declare uniqueESSymbolType?: Type; // UniqueESSymbol type for a symbol - declare declaredType?: Type; // Type of class, interface, enum, type alias, or type parameter - declare typeParameters?: TypeParameter[]; // Type parameters of type alias (undefined if non-generic) - declare outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type - declare instantiations?: Map; // Instantiations of generic type alias (undefined if non-generic) - declare aliasSymbol?: Symbol; // Alias associated with generic type alias instantiation - declare aliasTypeArguments?: readonly Type[] // Alias type arguments (if any) - declare inferredClassSymbol?: Map; // Symbol of an inferred ES5 constructor function - declare mapper?: TypeMapper; // Type mapper for instantiation alias - declare referenced?: boolean; // True if alias symbol has been referenced as a value that can be emitted - declare constEnumReferenced?: boolean; // True if alias symbol resolves to a const enum and is referenced as a value ('referenced' will be false) - declare containingType?: UnionOrIntersectionType; // Containing union or intersection type for synthetic property - declare leftSpread?: Symbol; // Left source for synthetic spread property - declare rightSpread?: Symbol; // Right source for synthetic spread property - declare syntheticOrigin?: Symbol; // For a property on a mapped or spread type, points back to the original property - declare isDiscriminantProperty?: boolean; // True if discriminant synthetic property - declare resolvedExports?: SymbolTable; // Resolved exports of module or combined early- and late-bound static members of a class. - declare resolvedMembers?: SymbolTable; // Combined early- and late-bound members of a symbol - declare exportsChecked?: boolean; // True if exports of external module have been checked - declare typeParametersChecked?: boolean; // True if type parameters of merged class and interface declarations have been checked. - declare isDeclarationWithCollidingName?: boolean; // True if symbol is block scoped redeclaration - declare bindingElement?: BindingElement; // Binding element associated with property symbol - declare exportsSomeValue?: boolean; // True if module exports some value (not just types) - declare enumKind?: EnumKind; // Enum declaration classification - declare originatingImport?: ImportDeclaration | ImportCall; // Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol` - declare lateSymbol?: Symbol; // Late-bound symbol for a computed property - declare specifierCache?: Map; // For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings - declare extendedContainers?: Symbol[]; // Containers (other than the parent) which this symbol is aliased in - declare extendedContainersByFile?: Map; // Containers (other than the parent) which this symbol is aliased in - declare variances?: VarianceFlags[]; // Alias symbol type argument variance cache - declare deferralConstituents?: Type[]; // Calculated list of constituents for a deferred type - declare deferralWriteConstituents?: Type[]; // Constituents of a deferred `writeType` - declare deferralParent?: Type; // Source union/intersection of a deferred type - declare cjsExportMerged?: Symbol; // Version of the symbol with all non export= exports merged with the export= target - declare typeOnlyDeclaration?: TypeOnlyAliasDeclaration | false; // First resolved alias declaration that makes the symbol only usable in type constructs - declare typeOnlyExportStarMap?: Map<__String, ExportDeclaration & { readonly isTypeOnly: true, readonly moduleSpecifier: Expression }>; // Set on a module symbol when some of its exports were resolved through a 'export type * from "mod"' declaration - declare typeOnlyExportStarName?: __String; // Set to the name of the symbol re-exported by an 'export type *' declaration, when different from the symbol name - declare isConstructorDeclaredProperty?: boolean; // Property declared through 'this.x = ...' assignment in constructor - declare tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; // Declaration associated with the tuple's label +export class SymbolLinks extends SpeculatableLinks { + declare private _symbolLinksBrand: any; + /** Type of value symbol */ + @SpeculatableCache accessor type: Type | undefined = undefined; + /** Type of value symbol in write contexts */ + @SpeculatableCache accessor writeType: Type | undefined = undefined; + /** Type associated with a late-bound symbol */ + @SpeculatableCache accessor nameType: Type | undefined = undefined; + /** Immediate target of an alias. May be another alias. Do not access directly, use `checker.getImmediateAliasedSymbol` instead. */ + declare immediateTarget?: Symbol; + /** Resolved (non-alias) target of an alias */ + declare aliasTarget?: Symbol; + /** Original version of an instantiated symbol */ + declare target?: Symbol; + /** UniqueESSymbol type for a symbol */ + declare uniqueESSymbolType?: Type; + /** Type of class, interface, enum, type alias, or type parameter */ + declare declaredType?: Type; + /** Type parameters of type alias (undefined if non-generic) */ + declare typeParameters?: TypeParameter[]; + /** Outer type parameters of anonymous object type */ + declare outerTypeParameters?: TypeParameter[]; + /** Instantiations of generic type alias (undefined if non-generic) */ + declare instantiations?: Map; + /** Alias associated with generic type alias instantiation */ + declare aliasSymbol?: Symbol; + /** Alias type arguments (if any) */ + declare aliasTypeArguments?: readonly Type[] + /** Symbol of an inferred ES5 constructor function */ + declare inferredClassSymbol?: Map; + /** Type mapper for instantiation alias */ + declare mapper?: TypeMapper; + /** True if alias symbol has been referenced as a value that can be emitted */ + declare referenced?: boolean; + /** True if alias symbol resolves to a const enum and is referenced as a value ('referenced' will be false) */ + declare constEnumReferenced?: boolean; + /** Containing union or intersection type for synthetic property */ + declare containingType?: UnionOrIntersectionType; + /** Left source for synthetic spread property */ + declare leftSpread?: Symbol; + /** Right source for synthetic spread property */ + declare rightSpread?: Symbol; + /** For a property on a mapped or spread type, points back to the original property */ + declare syntheticOrigin?: Symbol; + /** True if discriminant synthetic property */ + declare isDiscriminantProperty?: boolean; + /** Resolved exports of module or combined early- and late-bound static members of a class. */ + declare resolvedExports?: SymbolTable; + /** Combined early- and late-bound members of a symbol */ + declare resolvedMembers?: SymbolTable; + /** True if exports of external module have been checked */ + declare exportsChecked?: boolean; + /** True if type parameters of merged class and interface declarations have been checked. */ + declare typeParametersChecked?: boolean; + /** True if symbol is block scoped redeclaration */ + declare isDeclarationWithCollidingName?: boolean; + /** Binding element associated with property symbol */ + declare bindingElement?: BindingElement; + /** True if module exports some value (not just types) */ + declare exportsSomeValue?: boolean; + /** Enum declaration classification */ + declare enumKind?: EnumKind; + /** Import declaration which produced the symbol, present if the symbol is marked as uncallable but had call signatures in `resolveESModuleSymbol` */ + declare originatingImport?: ImportDeclaration | ImportCall; + /** Late-bound symbol for a computed property */ + declare lateSymbol?: Symbol; + /** For symbols corresponding to external modules, a cache of incoming path -> module specifier name mappings */ + declare specifierCache?: Map; + /** Containers (other than the parent) which this symbol is aliased in */ + declare extendedContainers?: Symbol[]; + /** Containers (other than the parent) which this symbol is aliased in */ + declare extendedContainersByFile?: Map; + /** Alias symbol type argument variance cache */ + declare variances?: VarianceFlags[]; + /** Calculated list of constituents for a deferred type */ + declare deferralConstituents?: Type[]; + /** Constituents of a deferred `writeType` */ + declare deferralWriteConstituents?: Type[]; + /** Source union/intersection of a deferred type */ + declare deferralParent?: Type; + /** Version of the symbol with all non export= exports merged with the export= target */ + declare cjsExportMerged?: Symbol; + /** First resolved alias declaration that makes the symbol only usable in type constructs */ + declare typeOnlyDeclaration?: TypeOnlyAliasDeclaration | false; + /** Set on a module symbol when some of its exports were resolved through a 'export type * from "mod"' declaration */ + declare typeOnlyExportStarMap?: Map<__String, ExportDeclaration & { readonly isTypeOnly: true, readonly moduleSpecifier: Expression }>; + /** Set to the name of the symbol re-exported by an 'export type *' declaration, when different from the symbol name */ + declare typeOnlyExportStarName?: __String; + /** Property declared through 'this.x = ...' assignment in constructor */ + declare isConstructorDeclaredProperty?: boolean; + /** Declaration associated with the tuple's label */ + declare tupleLabelDeclaration?: NamedTupleMember | ParameterDeclaration; declare accessibleChainCache?: Map; - declare filteredIndexSymbolCache?: Map //Symbol with applicable declarations + /** Symbol with applicable declarations */ + declare filteredIndexSymbolCache?: Map; - static override speculativeCaches = new Set([ "type", "writeType", "nameType" ]); + constructor( + host: SpeculationHost, + /** speculative epoch the associated symbol was manufactured in */ + public symbolEpoch = 0 // Assume lazily made links are for persistent epoch 0 symbols unless explicitly overridden + ) { + super(host); + } } /** @internal */ @@ -1486,6 +1595,7 @@ export interface TransientSymbolLinks extends SymbolLinks { /** @internal */ export interface TransientSymbol extends Symbol { links: TransientSymbolLinks; + epoch: number; } /** @internal */ @@ -1524,55 +1634,70 @@ export interface SerializedTypeEntry { // dprint-ignore /** @internal */ -export class NodeLinks extends SaveableLinks { - declare flags: NodeCheckFlags; // Set of flags specific to Node - declare resolvedType?: Type; // Cached type of type node - declare resolvedEnumType?: Type; // Cached constraint type from enum jsdoc tag - declare resolvedSignature?: Signature; // Cached signature of signature node or call expression - declare resolvedSymbol?: Symbol; // Cached name resolution result - declare resolvedIndexInfo?: IndexInfo; // Cached indexing info resolution result - declare effectsSignature?: Signature; // Signature with possible control flow effects - declare enumMemberValue?: string | number; // Constant value of enum member - declare isVisible?: boolean; // Is this node visible - declare containsArgumentsReference?: boolean; // Whether a function-like declaration contains an 'arguments' reference - declare hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context - declare jsxFlags?: JsxFlags; // flags for knowing what kind of element/attributes we're dealing with - declare resolvedJsxElementAttributesType?: Type; // resolved element attributes type of a JSX openinglike element - declare resolvedJsxElementAllAttributesType?: Type; // resolved all element attributes type of a JSX openinglike element - declare resolvedJSDocType?: Type; // Resolved type of a JSDoc type reference - declare switchTypes?: Type[]; // Cached array of switch case expression types - declare jsxNamespace?: Symbol | false; // Resolved jsx namespace symbol for this node - declare jsxImplicitImportContainer?: Symbol | false; // Resolved module symbol the implicit jsx import of this file should refer to - declare contextFreeType?: Type; // Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive - declare deferredNodes?: Set; // Set of nodes whose checking has been deferred - declare capturedBlockScopeBindings?: Symbol[]; // Block-scoped bindings captured beneath this part of an IterationStatement - declare outerTypeParameters?: TypeParameter[]; // Outer type parameters of anonymous object type - declare isExhaustive?: boolean | 0; // Is node an exhaustive switch statement (0 indicates in-process resolution) - declare skipDirectInference?: true; // Flag set by the API `getContextualType` call on a node when `Completions` is passed to force the checker to skip making inferences to a node's type - declare declarationRequiresScopeChange?: boolean; // Set by `useOuterVariableScopeInParameter` in checker when downlevel emit would change the name resolution scope inside of a parameter. - declare serializedTypes?: Map; // Collection of types serialized at this location - declare decoratorSignature?: Signature; // Signature for decorator as if invoked by the runtime. - declare spreadIndices?: { first: number | undefined, last: number | undefined }; // Indices of first and last spread elements in array literal - declare parameterInitializerContainsUndefined?: boolean; // True if this is a parameter declaration whose type annotation contains "undefined". - declare fakeScopeForSignatureDeclaration?: "params" | "typeParams"; // If present, this is a fake scope injected into an enclosing declaration chain. - declare assertionExpressionType?: Type; // Cached type of the expression of a type assertion - constructor() { - super(); - this.flags = NodeCheckFlags.None; - } - - static override speculativeCaches = new Set([ - "flags", - "resolvedType", - "resolvedEnumType", - "resolvedSignature", - "resolvedSymbol", - "resolvedIndexInfo", - "effectsSignature", - "switchTypes", - "contextFreeType", - "assertionExpressionType", - ]); +export class NodeLinks extends SpeculatableLinks { + /** Set of flags specific to Node */ + @SpeculatableCache accessor flags: NodeCheckFlags = NodeCheckFlags.None; + /** Cached type of type node */ + @SpeculatableCache accessor resolvedType: Type | undefined = undefined; + /** Cached constraint type from enum jsdoc tag */ + @SpeculatableCache accessor resolvedEnumType: Type | undefined = undefined; + /** Cached signature of signature node or call expression */ + @SpeculatableCache accessor resolvedSignature: Signature | undefined = undefined; + /** Cached name resolution result */ + @SpeculatableCache accessor resolvedSymbol: Symbol | undefined = undefined; + /** Cached indexing info resolution result */ + @SpeculatableCache accessor resolvedIndexInfo: IndexInfo | undefined = undefined; + /** Signature with possible control flow effects */ + @SpeculatableCache accessor effectsSignature: Signature | undefined = undefined; + /** Cached array of switch case expression types */ + @SpeculatableCache accessor switchTypes: Type[] | undefined = undefined; + /** Cached context-free type used by the first pass of inference; used when a function's return is partially contextually sensitive */ + @SpeculatableCache accessor contextFreeType: Type | undefined = undefined; + /** Cached type of the expression of a type assertion */ + @SpeculatableCache accessor assertionExpressionType: Type | undefined = undefined; + + /** Constant value of enum member */ + declare enumMemberValue?: string | number; + /** Is this node visible */ + declare isVisible?: boolean; + /** Whether a function-like declaration contains an 'arguments' reference */ + declare containsArgumentsReference?: boolean; + /** Cache boolean if we report statements in ambient context */ + declare hasReportedStatementInAmbientContext?: boolean; + /** flags for knowing what kind of element/attributes we're dealing with */ + declare jsxFlags?: JsxFlags; + /** resolved element attributes type of a JSX openinglike element */ + declare resolvedJsxElementAttributesType?: Type; + /** resolved all element attributes type of a JSX openinglike element */ + declare resolvedJsxElementAllAttributesType?: Type; + /** Resolved type of a JSDoc type reference */ + declare resolvedJSDocType?: Type; + /** Resolved jsx namespace symbol for this node */ + declare jsxNamespace?: Symbol | false; + /** Resolved module symbol the implicit jsx import of this file should refer to */ + declare jsxImplicitImportContainer?: Symbol | false; + /** Set of nodes whose checking has been deferred */ + declare deferredNodes?: Set; + /** Block-scoped bindings captured beneath this part of an IterationStatement */ + declare capturedBlockScopeBindings?: Symbol[]; + /** Outer type parameters of anonymous object type */ + declare outerTypeParameters?: TypeParameter[]; + /** Is node an exhaustive switch statement (0 indicates in-process resolution) */ + declare isExhaustive?: boolean | 0; + /** Flag set by the API `getContextualType` call on a node when `Completions` is passed to force the checker to skip making inferences to a node's type */ + declare skipDirectInference?: true; + /** Set by `useOuterVariableScopeInParameter` in checker when downlevel emit would change the name resolution scope inside of a parameter. */ + declare declarationRequiresScopeChange?: boolean; + /** Collection of types serialized at this location */ + declare serializedTypes?: Map; + /** Signature for decorator as if invoked by the runtime. */ + declare decoratorSignature?: Signature; + /** Indices of first and last spread elements in array literal */ + declare spreadIndices?: { first: number | undefined, last: number | undefined }; + /** True if this is a parameter declaration whose type annotation contains "undefined". */ + declare parameterInitializerContainsUndefined?: boolean; + /** If present, this is a fake scope injected into an enclosing declaration chain. */ + declare fakeScopeForSignatureDeclaration?: "params" | "typeParams"; } /** @internal */ @@ -1609,11 +1734,20 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // List of all caches whose state should be saved and potentially restored on completion of a speculative typechecking operation var speculativeCaches: (any[] | Map | Set | DiagnosticCollection)[] = []; - // Transient symbols store their links directly on them, so each transient symbol is also a small speculative cache. - // WeakRef is first supported in node 14 (our earliest test version) - unlike weakmap and weakset which are node 0.12 - // Do note that this works without WeakRefs, but would mean we can leak memory via unbounded transient symbol creation pretty easily. - // This has to be an array of weak refs and not a weak map or weak set because we need to iterate over them to attempt to save their state. - var transientSymbols: WeakRef[] = []; + /** + * The id of the current speculative execution environment - used by speculation helpers to avoid eagerly doing work. + * + * This is monotonically increasing, and basically represents a slice of execution time within the checker that we want to + * be able to uniquely refer to. + */ + var currentSpeculativeEpoch = 0; + // The set of speculative environment ids whose contents have been discarded + var discardedSpeculativeEpochs = new Set(); + // The speculation host object used by symbol and node links to associate their speculation state with this checker's speculation state + var speculationHost: SpeculationHost = { + getCurrentSpeculativeEpoch() { return currentSpeculativeEpoch; }, + getDiscardedSpeculativeEpochs() { return discardedSpeculativeEpochs; }, + } var deferredDiagnosticsCallbacks: (() => void)[] = registerSpeculativeCache([]); @@ -2433,11 +2567,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var suggestionCount = 0; var maximumSuggestionCount = 10; var mergedSymbols: Symbol[] = []; - var symbolLinks: SymbolLinks[] = registerSpeculativeCache([]); - var nodeLinks: NodeLinks[] = registerSpeculativeCache([]); + var symbolLinks: SymbolLinks[] = []; + var nodeLinks: NodeLinks[] = []; var flowLoopCaches: Map[] = registerSpeculativeCache([]); - var flowLoopNodes: FlowNode[] = []; - var flowLoopKeys: string[] = []; + var flowLoopNodes: FlowNode[] = registerSpeculativeCache([]); + var flowLoopKeys: string[] = registerSpeculativeCache([]); var flowLoopTypes: Type[][] = registerSpeculativeCache([]); var sharedFlowNodes: FlowNode[] = registerSpeculativeCache([]); var sharedFlowTypes: FlowType[] = registerSpeculativeCache([]); @@ -2686,9 +2820,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function createSymbol(flags: SymbolFlags, name: __String, checkFlags?: CheckFlags) { symbolCount++; const symbol = new Symbol(flags | SymbolFlags.Transient, name) as TransientSymbol; - symbol.links = new SymbolLinks() as TransientSymbolLinks; + symbol.epoch = currentSpeculativeEpoch; + symbol.links = new SymbolLinks(speculationHost, symbol.epoch) as TransientSymbolLinks; symbol.links.checkFlags = checkFlags || CheckFlags.None; - transientSymbols.push(new WeakRef(symbol)); return symbol; } @@ -2953,12 +3087,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function getSymbolLinks(symbol: Symbol): SymbolLinks { if (symbol.flags & SymbolFlags.Transient) return (symbol as TransientSymbol).links; const id = getSymbolId(symbol); - return symbolLinks[id] ??= new SymbolLinks(); + return symbolLinks[id] ??= new SymbolLinks(speculationHost); } function getNodeLinks(node: Node): NodeLinks { const nodeId = getNodeId(node); - return nodeLinks[nodeId] || (nodeLinks[nodeId] = new (NodeLinks as any)()); + return nodeLinks[nodeId] ??= new NodeLinks(speculationHost); } function isGlobalSourceFile(node: Node) { @@ -49025,13 +49159,21 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { * @param cb Speculation callback, operations performed within this context will be rewound and uncached unless the helper returns a truthy value */ function speculate(cb: () => T): T | undefined { + currentSpeculativeEpoch++; + const startEpoch = currentSpeculativeEpoch; const initialState = snapshotCheckerState(); const result = cb(); + const endEpoch = currentSpeculativeEpoch; + currentSpeculativeEpoch++; // success or fail, the end of a speculative context marks a new epoch if (!result) { + for (let i = startEpoch; i <= endEpoch; i++) { + // Even if intermediate speculation calls worked out, we're discarding this one, so + // we need to mark all epochs that occured during this speculation call as discarded + discardedSpeculativeEpochs.add(i); + } restoreCheckerState(initialState); return undefined; } - transientSymbols = concatenate(initialState.transientSymbols, transientSymbols); return result; } @@ -49042,35 +49184,18 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { interface SavedCheckerState { restores: (() => void)[]; - transientSymbols: typeof transientSymbols; } function snapshotCheckerState(): SavedCheckerState { - const state: SavedCheckerState = { restores: concatenate(map(speculativeCaches, save), mapDefined(transientSymbols, saveTransientSymbolLink)), transientSymbols }; - transientSymbols = []; + const state: SavedCheckerState = { restores: map(speculativeCaches, save) }; return state; - function saveTransientSymbolLink(ref: WeakRef): (() => void) | undefined { - const res = ref.deref(); - if (res) { - return save(ref); - } - } - // TODO: Override error reporting functions to just defer work until speculation // helper is confirmed as locked-in, to avoid the work of building diagnostics until // we know we're actually going to use them. - function save(cache: (typeof speculativeCaches)[number] | WeakRef): () => void { + function save(cache: (typeof speculativeCaches)[number]): () => void { if (Array.isArray(cache)) { - for (const k in cache) { - const v = cache[k]; - if (v instanceof NodeLinks || v instanceof SymbolLinks) { - return saveLinksArray(cache); - } - break; - } - // A totally empty links array may get `save`'d as a normal array. That should be fine - we should reset it to empty. return saveArray(cache); } else if (cache instanceof Map) { @@ -49079,45 +49204,15 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else if (cache instanceof Set) { return saveSet(cache); } - else if (cache instanceof WeakRef) { - return saveLinks(cache); - } else if (cache.add! && cache.getDiagnostics!) { // eslint-disable-line @typescript-eslint/no-unnecessary-type-assertion return saveDiagnosticCollection(cache); } return Debug.fail("Unknown speculative cache type"); } - function saveLinks(cache: WeakRef) { - const saved = cache.deref()?.links.save(); - if (!saved) { - return noop; - } - return () => cache.deref()?.links.restore(saved); - } - - function saveLinksArray(cache: NodeLinks[] | SymbolLinks[]) { - const og: Partial[] = []; - for (const k in cache) { - if (cache[k]) { - og[k] = cache[k].save(); - } - } - return () => { - for (const k in cache) { - if (!og[k]) { - // TODO: there has to be a way to phase the types/cast to make these directly callable - cache[k].restore.call(cache[k], undefined); - } - else { - cache[k].restore.call(cache[k], og[k]); - } - } - } - } - // TODO: All these save/restore methods are as naive as you can get right now, which means speculation - // is insanely expensive, as it is eagerly saving off the checker state + // is insanely expensive, as it is eagerly saving off the checker state. + // Where possible, most things should be migrated to lazy caches, like the @SpeculatableCache decorator sets up. function saveArray(cache: unknown[]) { const original = cache.slice(); return () => { @@ -49158,7 +49253,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { for (const restore of state.restores) { restore(); } - transientSymbols = state.transientSymbols; // simply discard the current array - all those transient symbols should fall out of scope. } function initializeTypeChecker() { diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index 0691623813570..c4d719b1bd9c6 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -8,6 +8,7 @@ "target": "es2021", "module": "CommonJS", "moduleResolution": "node", + "experimentalDecorators": true, "declaration": true, "declarationMap": true, diff --git a/tests/cases/compiler/APILibCheck.ts b/tests/cases/compiler/APILibCheck.ts index 38821a58b0b76..6623e0314bce5 100644 --- a/tests/cases/compiler/APILibCheck.ts +++ b/tests/cases/compiler/APILibCheck.ts @@ -2,6 +2,7 @@ // @noImplicitAny: true // @strictNullChecks: true // @lib: es2018 +// @target: es2015 // @exactOptionalPropertyTypes: true // @filename: node_modules/typescript/package.json From 5196f052f27759fe98d2d6e07af10079cd249f7f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 29 Feb 2024 11:25:27 -0800 Subject: [PATCH 10/18] Expedite and make consistent signature error reporting --- src/compiler/checker.ts | 25 ++++-- src/compiler/utilities.ts | 12 +++ .../reference/bigintWithLib.errors.txt | 12 +++ .../checkJsxChildrenCanBeTupleType.errors.txt | 2 + ...StringLiteralsInJsxAttributes02.errors.txt | 8 +- ...fixingTypeParametersRepeatedly2.errors.txt | 10 ++- ...functionConstraintSatisfaction2.errors.txt | 4 + ...edMethodWithOverloadedArguments.errors.txt | 8 ++ ...lWithGenericSignatureArguments3.errors.txt | 12 +-- .../intraExpressionInferences.errors.txt | 5 +- .../intraExpressionInferences.symbols | 2 - .../reference/intraExpressionInferences.types | 18 ++--- .../iteratorSpreadInArray6.errors.txt | 8 +- .../keyofAndIndexedAccessErrors.errors.txt | 2 + ...nWithConstraintCheckingDeferred.errors.txt | 3 + .../overloadsWithProvisionalErrors.types | 8 +- .../reference/promisePermutations.errors.txt | 12 +++ .../reference/promisePermutations2.errors.txt | 12 +++ .../reference/promisePermutations3.errors.txt | 12 +++ ...actDefaultPropsInferenceSuccess.errors.txt | 10 +++ ...eStringsWithOverloadResolution1.errors.txt | 21 +++++ ...ingsWithOverloadResolution1_ES6.errors.txt | 21 +++++ .../incremental/serializing-error-chains.js | 78 +++++++------------ .../tsxNotUsingApparentTypeOfSFC.errors.txt | 3 + ...elessFunctionComponentOverload5.errors.txt | 8 +- .../unionThisTypeInFunctions.errors.txt | 16 +--- 26 files changed, 227 insertions(+), 105 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ac923c187ef74..c484f148f1782 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -905,6 +905,7 @@ import { PatternAmbientModule, PlusToken, PostfixUnaryExpression, + prefixDiagnosticWithMessageChain, PrefixUnaryExpression, PrivateIdentifier, Program, @@ -35001,6 +35002,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // foo(0); // let candidatesForArgumentError: Signature[] | undefined; + let candidateArgumentErrors: (readonly Diagnostic[])[] | undefined; let candidateForArgumentArityError: Signature | undefined; let candidateForTypeArgumentError: Signature | undefined; let result: Signature | undefined; @@ -35061,9 +35063,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (headMessage) { chain = chainDiagnosticMessages(chain, headMessage); } - const diags = getSignatureApplicabilityError(node, args, last, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, () => chain); + const diags = candidateArgumentErrors![candidateArgumentErrors!.length - 1]; if (diags) { - for (const d of diags) { + for (let d of diags) { + d = prefixDiagnosticWithMessageChain(d, chain); if (last.declaration && candidatesForArgumentError.length > 3) { addRelatedInfo(d, createDiagnosticForNode(last.declaration, Diagnostics.The_last_overload_is_declared_here)); } @@ -35083,14 +35086,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { let i = 0; for (const c of candidatesForArgumentError) { const chain = () => chainDiagnosticMessages(/*details*/ undefined, Diagnostics.Overload_0_of_1_2_gave_the_following_error, i + 1, candidates.length, signatureToString(c)); - const diags = getSignatureApplicabilityError(node, args, c, assignableRelation, CheckMode.Normal, /*reportErrors*/ true, chain); + const diags = candidateArgumentErrors![i]; if (diags) { if (diags.length <= min) { min = diags.length; minIndex = i; } max = Math.max(max, diags.length); - allDiagnostics.push(diags); + allDiagnostics.push(map(diags, d => prefixDiagnosticWithMessageChain(d, chain()))); } else { Debug.fail("No error for 3 or fewer overload signatures"); @@ -35143,6 +35146,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { function addImplementationSuccessElaboration(failed: Signature, diagnostic: Diagnostic) { const oldCandidatesForArgumentError = candidatesForArgumentError; + const oldCandidateArgumentErrors = candidateArgumentErrors; const oldCandidateForArgumentArityError = candidateForArgumentArityError; const oldCandidateForTypeArgumentError = candidateForTypeArgumentError; @@ -35158,12 +35162,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } candidatesForArgumentError = oldCandidatesForArgumentError; + candidateArgumentErrors = oldCandidateArgumentErrors; candidateForArgumentArityError = oldCandidateForArgumentArityError; candidateForTypeArgumentError = oldCandidateForTypeArgumentError; } function chooseOverload(candidates: Signature[], relation: Map, isSingleNonGenericCandidate: boolean, signatureHelpTrailingComma = false) { candidatesForArgumentError = undefined; + candidateArgumentErrors = undefined; candidateForArgumentArityError = undefined; candidateForTypeArgumentError = undefined; @@ -35172,8 +35178,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (some(typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { return undefined; } - if (getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { + let diags: readonly Diagnostic[] | undefined; + if (diags = getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ true, /*containingMessageChain*/ undefined)) { candidatesForArgumentError = [candidate]; + candidateArgumentErrors = [diags]; return undefined; } return candidate; @@ -35213,9 +35221,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { else { checkCandidate = candidate; } - if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { + let diags: readonly Diagnostic[] | undefined; + if (diags = getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ true, /*containingMessageChain*/ undefined)) { // Give preference to error candidates that have no rest parameters (as they are more specific) (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); + (candidateArgumentErrors ||= []).push(diags); return false; } if (argCheckMode) { @@ -35233,9 +35243,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } } - if (getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ false, /*containingMessageChain*/ undefined)) { + if (diags = getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ true, /*containingMessageChain*/ undefined)) { // Give preference to error candidates that have no rest parameters (as they are more specific) (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); + (candidateArgumentErrors ||= []).push(diags); return false; } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 8074346cf332c..18f42f98cd549 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -8480,6 +8480,18 @@ export function createCompilerDiagnosticFromMessageChain(chain: DiagnosticMessag }; } +/** @internal */ +export function prefixDiagnosticWithMessageChain(base: Diagnostic, chain: DiagnosticMessageChain | undefined): Diagnostic { + if (!chain) return base; + concatenateDiagnosticMessageChains(chain, createDiagnosticMessageChainFromDiagnostic(base)); // Mutates `chain` to continue with `base`'s message chain + return { + ...base, + code: chain.code, + category: chain.category, + messageText: chain.next ? chain : chain.messageText, + }; +} + /** @internal */ export function chainDiagnosticMessages(details: DiagnosticMessageChain | DiagnosticMessageChain[] | undefined, message: DiagnosticMessage, ...args: DiagnosticArguments): DiagnosticMessageChain { let text = getLocaleSpecificMessage(message); diff --git a/tests/baselines/reference/bigintWithLib.errors.txt b/tests/baselines/reference/bigintWithLib.errors.txt index aa402ec0cba5c..74057e3a2431a 100644 --- a/tests/baselines/reference/bigintWithLib.errors.txt +++ b/tests/baselines/reference/bigintWithLib.errors.txt @@ -18,8 +18,14 @@ bigintWithLib.ts(31,35): error TS2769: No overload matches this call. Argument of type 'number[]' is not assignable to parameter of type 'number'. Overload 2 of 3, '(array: Iterable): BigUint64Array', gave the following error. Argument of type 'number[]' is not assignable to parameter of type 'Iterable'. + The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. + Type 'IteratorResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. + Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. + Type 'number' is not assignable to type 'bigint'. Overload 3 of 3, '(buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigUint64Array', gave the following error. Argument of type 'number[]' is not assignable to parameter of type 'ArrayBufferLike'. + Type 'number[]' is missing the following properties from type 'SharedArrayBuffer': byteLength, [Symbol.species], [Symbol.toStringTag] bigintWithLib.ts(36,13): error TS2540: Cannot assign to 'length' because it is a read-only property. bigintWithLib.ts(43,25): error TS2345: Argument of type 'number' is not assignable to parameter of type 'bigint'. bigintWithLib.ts(46,26): error TS2345: Argument of type 'number' is not assignable to parameter of type 'bigint'. @@ -81,8 +87,14 @@ bigintWithLib.ts(46,26): error TS2345: Argument of type 'number' is not assignab !!! error TS2769: Argument of type 'number[]' is not assignable to parameter of type 'number'. !!! error TS2769: Overload 2 of 3, '(array: Iterable): BigUint64Array', gave the following error. !!! error TS2769: Argument of type 'number[]' is not assignable to parameter of type 'Iterable'. +!!! error TS2769: The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. +!!! error TS2769: Type 'IteratorResult' is not assignable to type 'IteratorResult'. +!!! error TS2769: Type 'IteratorYieldResult' is not assignable to type 'IteratorResult'. +!!! error TS2769: Type 'IteratorYieldResult' is not assignable to type 'IteratorYieldResult'. +!!! error TS2769: Type 'number' is not assignable to type 'bigint'. !!! error TS2769: Overload 3 of 3, '(buffer: ArrayBufferLike, byteOffset?: number, length?: number): BigUint64Array', gave the following error. !!! error TS2769: Argument of type 'number[]' is not assignable to parameter of type 'ArrayBufferLike'. +!!! error TS2769: Type 'number[]' is missing the following properties from type 'SharedArrayBuffer': byteLength, [Symbol.species], [Symbol.toStringTag] bigUintArray = new BigUint64Array(new ArrayBuffer(80)); bigUintArray = new BigUint64Array(new ArrayBuffer(80), 8); bigUintArray = new BigUint64Array(new ArrayBuffer(80), 8, 3); diff --git a/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt b/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt index 5736290f8a104..cc60334c1e39b 100644 --- a/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt +++ b/tests/baselines/reference/checkJsxChildrenCanBeTupleType.errors.txt @@ -8,6 +8,7 @@ checkJsxChildrenCanBeTupleType.tsx(17,18): error TS2769: No overload matches thi Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly'. Types of property 'children' are incompatible. Type '[Element, Element, Element]' is not assignable to type '[ReactNode, ReactNode]'. + Source has 3 element(s) but target allows only 2. ==== checkJsxChildrenCanBeTupleType.tsx (1 errors) ==== @@ -39,6 +40,7 @@ checkJsxChildrenCanBeTupleType.tsx(17,18): error TS2769: No overload matches thi !!! error TS2769: Type '{ children: [Element, Element, Element]; }' is not assignable to type 'Readonly'. !!! error TS2769: Types of property 'children' are incompatible. !!! error TS2769: Type '[Element, Element, Element]' is not assignable to type '[ReactNode, ReactNode]'. +!!! error TS2769: Source has 3 element(s) but target allows only 2.

diff --git a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt index 4adb70251deaf..e6be2d50b6119 100644 --- a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt +++ b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt @@ -3,14 +3,14 @@ file.tsx(27,64): error TS2769: No overload matches this call. Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. Overload 2 of 2, '(linkProps: LinkProps): Element', gave the following error. - Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. + Type '{ extra: true; onClick: (k: any) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. file.tsx(28,13): error TS2769: No overload matches this call. Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. Overload 2 of 2, '(linkProps: LinkProps): Element', gave the following error. - Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. + Type '{ onClick: (k: any) => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. file.tsx(29,43): error TS2769: No overload matches this call. Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. @@ -66,7 +66,7 @@ file.tsx(36,44): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assi !!! error TS2769: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. !!! error TS2769: Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. !!! error TS2769: Overload 2 of 2, '(linkProps: LinkProps): Element', gave the following error. -!!! error TS2769: Type '{ extra: true; onClick: (k: "left" | "right") => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. +!!! error TS2769: Type '{ extra: true; onClick: (k: any) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. !!! error TS2769: Property 'extra' does not exist on type 'IntrinsicAttributes & LinkProps'. const b2 = {console.log(k)}} extra />; // k has type "left" | "right" ~~~~~~~~~~ @@ -75,7 +75,7 @@ file.tsx(36,44): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assi !!! error TS2769: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. !!! error TS2769: Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. !!! error TS2769: Overload 2 of 2, '(linkProps: LinkProps): Element', gave the following error. -!!! error TS2769: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. +!!! error TS2769: Type '{ onClick: (k: any) => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. !!! error TS2769: Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. const b3 = ; // goTo has type"home" | "contact" ~~~~~ diff --git a/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt b/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt index 799646ff47897..98c0c4640b57f 100644 --- a/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt +++ b/tests/baselines/reference/fixingTypeParametersRepeatedly2.errors.txt @@ -1,9 +1,9 @@ fixingTypeParametersRepeatedly2.ts(11,32): error TS2741: Property 'toBase' is missing in type 'Base' but required in type 'Derived'. fixingTypeParametersRepeatedly2.ts(17,32): error TS2769: No overload matches this call. Overload 1 of 2, '(x: Derived, func: (p: Derived) => Derived): Derived', gave the following error. - Type 'Base' is not assignable to type 'Derived'. + Property 'toBase' is missing in type 'Base' but required in type 'Derived'. Overload 2 of 2, '(x: Derived, func: (p: Derived) => Derived): Derived', gave the following error. - Type 'Base' is not assignable to type 'Derived'. + Property 'toBase' is missing in type 'Base' but required in type 'Derived'. ==== fixingTypeParametersRepeatedly2.ts (2 errors) ==== @@ -31,8 +31,10 @@ fixingTypeParametersRepeatedly2.ts(17,32): error TS2769: No overload matches thi ~~~~~~~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(x: Derived, func: (p: Derived) => Derived): Derived', gave the following error. -!!! error TS2769: Type 'Base' is not assignable to type 'Derived'. +!!! error TS2769: Property 'toBase' is missing in type 'Base' but required in type 'Derived'. !!! error TS2769: Overload 2 of 2, '(x: Derived, func: (p: Derived) => Derived): Derived', gave the following error. -!!! error TS2769: Type 'Base' is not assignable to type 'Derived'. +!!! error TS2769: Property 'toBase' is missing in type 'Base' but required in type 'Derived'. +!!! related TS2728 fixingTypeParametersRepeatedly2.ts:5:5: 'toBase' is declared here. !!! related TS6502 fixingTypeParametersRepeatedly2.ts:15:37: The expected type comes from the return type of this signature. +!!! related TS2728 fixingTypeParametersRepeatedly2.ts:5:5: 'toBase' is declared here. !!! related TS6502 fixingTypeParametersRepeatedly2.ts:16:37: The expected type comes from the return type of this signature. \ No newline at end of file diff --git a/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt b/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt index 2bb7f3f550c7b..d9249711d1d6a 100644 --- a/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt +++ b/tests/baselines/reference/functionConstraintSatisfaction2.errors.txt @@ -23,6 +23,8 @@ functionConstraintSatisfaction2.ts(37,10): error TS2345: Argument of type 'T' is Type 'void' is not assignable to type 'string'. functionConstraintSatisfaction2.ts(38,10): error TS2345: Argument of type 'U' is not assignable to parameter of type '(x: string) => string'. Type 'T' is not assignable to type '(x: string) => string'. + Type '() => void' is not assignable to type '(x: string) => string'. + Type 'void' is not assignable to type 'string'. ==== functionConstraintSatisfaction2.ts (13 errors) ==== @@ -102,5 +104,7 @@ functionConstraintSatisfaction2.ts(38,10): error TS2345: Argument of type 'U' is ~ !!! error TS2345: Argument of type 'U' is not assignable to parameter of type '(x: string) => string'. !!! error TS2345: Type 'T' is not assignable to type '(x: string) => string'. +!!! error TS2345: Type '() => void' is not assignable to type '(x: string) => string'. +!!! error TS2345: Type 'void' is not assignable to type 'string'. } \ No newline at end of file diff --git a/tests/baselines/reference/genericCallToOverloadedMethodWithOverloadedArguments.errors.txt b/tests/baselines/reference/genericCallToOverloadedMethodWithOverloadedArguments.errors.txt index 42fe31432f26b..653b071b3b4cc 100644 --- a/tests/baselines/reference/genericCallToOverloadedMethodWithOverloadedArguments.errors.txt +++ b/tests/baselines/reference/genericCallToOverloadedMethodWithOverloadedArguments.errors.txt @@ -9,6 +9,7 @@ genericCallToOverloadedMethodWithOverloadedArguments.ts(52,38): error TS2769: No Overload 2 of 2, '(cb: (x: number) => Promise, error?: (error: any) => Promise): Promise', gave the following error. Argument of type '{ (n: number): Promise; (s: string): Promise; }' is not assignable to parameter of type '(x: number) => Promise'. Type 'Promise' is not assignable to type 'Promise'. + Type 'number' is not assignable to type 'string'. genericCallToOverloadedMethodWithOverloadedArguments.ts(68,38): error TS2769: No overload matches this call. Overload 1 of 3, '(cb: (x: number) => Promise): Promise', gave the following error. Argument of type '{ (n: number): Promise; (s: string): Promise; }' is not assignable to parameter of type '(x: number) => Promise'. @@ -17,9 +18,11 @@ genericCallToOverloadedMethodWithOverloadedArguments.ts(68,38): error TS2769: No Overload 2 of 3, '(cb: (x: number) => Promise, error?: (error: any) => Promise): Promise', gave the following error. Argument of type '{ (n: number): Promise; (s: string): Promise; }' is not assignable to parameter of type '(x: number) => Promise'. Type 'Promise' is not assignable to type 'Promise'. + Type 'number' is not assignable to type 'string'. Overload 3 of 3, '(cb: (x: number) => Promise, error?: (error: any) => string, progress?: (preservation: any) => void): Promise', gave the following error. Argument of type '{ (n: number): Promise; (s: string): Promise; }' is not assignable to parameter of type '(x: number) => Promise'. Type 'Promise' is not assignable to type 'Promise'. + Type 'number' is not assignable to type 'string'. genericCallToOverloadedMethodWithOverloadedArguments.ts(84,38): error TS2769: No overload matches this call. Overload 1 of 2, '(cb: (x: number) => Promise): Promise', gave the following error. Argument of type '{ (n: number): Promise; (s: string): Promise; (b: boolean): Promise; }' is not assignable to parameter of type '(x: number) => Promise'. @@ -28,6 +31,7 @@ genericCallToOverloadedMethodWithOverloadedArguments.ts(84,38): error TS2769: No Overload 2 of 2, '(cb: (x: number) => Promise, error?: (error: any) => Promise): Promise', gave the following error. Argument of type '{ (n: number): Promise; (s: string): Promise; (b: boolean): Promise; }' is not assignable to parameter of type '(x: number) => Promise'. Type 'Promise' is not assignable to type 'Promise'. + Type 'number' is not assignable to type 'boolean'. ==== genericCallToOverloadedMethodWithOverloadedArguments.ts (4 errors) ==== @@ -96,6 +100,7 @@ genericCallToOverloadedMethodWithOverloadedArguments.ts(84,38): error TS2769: No !!! error TS2769: Overload 2 of 2, '(cb: (x: number) => Promise, error?: (error: any) => Promise): Promise', gave the following error. !!! error TS2769: Argument of type '{ (n: number): Promise; (s: string): Promise; }' is not assignable to parameter of type '(x: number) => Promise'. !!! error TS2769: Type 'Promise' is not assignable to type 'Promise'. +!!! error TS2769: Type 'number' is not assignable to type 'string'. } ////////////////////////////////////// @@ -121,9 +126,11 @@ genericCallToOverloadedMethodWithOverloadedArguments.ts(84,38): error TS2769: No !!! error TS2769: Overload 2 of 3, '(cb: (x: number) => Promise, error?: (error: any) => Promise): Promise', gave the following error. !!! error TS2769: Argument of type '{ (n: number): Promise; (s: string): Promise; }' is not assignable to parameter of type '(x: number) => Promise'. !!! error TS2769: Type 'Promise' is not assignable to type 'Promise'. +!!! error TS2769: Type 'number' is not assignable to type 'string'. !!! error TS2769: Overload 3 of 3, '(cb: (x: number) => Promise, error?: (error: any) => string, progress?: (preservation: any) => void): Promise', gave the following error. !!! error TS2769: Argument of type '{ (n: number): Promise; (s: string): Promise; }' is not assignable to parameter of type '(x: number) => Promise'. !!! error TS2769: Type 'Promise' is not assignable to type 'Promise'. +!!! error TS2769: Type 'number' is not assignable to type 'string'. } ////////////////////////////////////// @@ -149,5 +156,6 @@ genericCallToOverloadedMethodWithOverloadedArguments.ts(84,38): error TS2769: No !!! error TS2769: Overload 2 of 2, '(cb: (x: number) => Promise, error?: (error: any) => Promise): Promise', gave the following error. !!! error TS2769: Argument of type '{ (n: number): Promise; (s: string): Promise; (b: boolean): Promise; }' is not assignable to parameter of type '(x: number) => Promise'. !!! error TS2769: Type 'Promise' is not assignable to type 'Promise'. +!!! error TS2769: Type 'number' is not assignable to type 'boolean'. } \ No newline at end of file diff --git a/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt b/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt index 5fd2927b27460..17f7dd29d63ba 100644 --- a/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt +++ b/tests/baselines/reference/genericCallWithGenericSignatureArguments3.errors.txt @@ -1,9 +1,9 @@ -genericCallWithGenericSignatureArguments3.ts(32,19): error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => 1' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => 1'. +genericCallWithGenericSignatureArguments3.ts(32,19): error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => number' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => number'. Types of parameters 'a1' and 'x' are incompatible. Type '(a: string) => boolean' is not assignable to type '(y: string) => string'. Type 'boolean' is not assignable to type 'string'. -genericCallWithGenericSignatureArguments3.ts(33,69): error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => 1'. - Type 'number' is not assignable to type '(n: Object) => 1'. +genericCallWithGenericSignatureArguments3.ts(33,69): error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => number'. + Type 'number' is not assignable to type '(n: Object) => number'. ==== genericCallWithGenericSignatureArguments3.ts (2 errors) ==== @@ -40,11 +40,11 @@ genericCallWithGenericSignatureArguments3.ts(33,69): error TS2345: Argument of t var x: (a: string) => boolean; var r11 = foo2(x, (a1: (y: string) => string) => (n: Object) => 1, (a2: (z: string) => string) => 2); // error ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => 1' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => 1'. +!!! error TS2345: Argument of type '(a1: (y: string) => string) => (n: Object) => number' is not assignable to parameter of type '(x: (a: string) => boolean) => (n: Object) => number'. !!! error TS2345: Types of parameters 'a1' and 'x' are incompatible. !!! error TS2345: Type '(a: string) => boolean' is not assignable to type '(y: string) => string'. !!! error TS2345: Type 'boolean' is not assignable to type 'string'. var r12 = foo2(x, (a1: (y: string) => boolean) => (n: Object) => 1, (a2: (z: string) => boolean) => 2); // error ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => 1'. -!!! error TS2345: Type 'number' is not assignable to type '(n: Object) => 1'. \ No newline at end of file +!!! error TS2345: Argument of type '(a2: (z: string) => boolean) => number' is not assignable to parameter of type '(x: (z: string) => boolean) => (n: Object) => number'. +!!! error TS2345: Type 'number' is not assignable to type '(n: Object) => number'. \ No newline at end of file diff --git a/tests/baselines/reference/intraExpressionInferences.errors.txt b/tests/baselines/reference/intraExpressionInferences.errors.txt index 82da18c788e9b..286942fbe9e16 100644 --- a/tests/baselines/reference/intraExpressionInferences.errors.txt +++ b/tests/baselines/reference/intraExpressionInferences.errors.txt @@ -2,10 +2,9 @@ intraExpressionInferences.ts(131,5): error TS2322: Type '(inputs: Unwrap<{ num: Call signature return types '{ bool: any; str: number; }' and 'Unwrap<{ bool: Wrapper; str: Wrapper; }>' are incompatible. The types of 'str' are incompatible between these types. Type 'number' is not assignable to type 'string'. -intraExpressionInferences.ts(133,26): error TS2339: Property 'nonexistent' does not exist on type 'Unwrap<{ num: Wrapper; str: Wrapper; }>'. -==== intraExpressionInferences.ts (2 errors) ==== +==== intraExpressionInferences.ts (1 errors) ==== // Repros from #47599 declare function callIt(obj: { @@ -145,8 +144,6 @@ intraExpressionInferences.ts(133,26): error TS2339: Property 'nonexistent' does !!! related TS6500 intraExpressionInferences.ts:113:5: The expected type comes from property 'map' which is declared here on type 'MappingComponent<{ num: Wrapper; str: Wrapper; }, { bool: Wrapper; str: Wrapper; }>' return { bool: inputs.nonexistent, - ~~~~~~~~~~~ -!!! error TS2339: Property 'nonexistent' does not exist on type 'Unwrap<{ num: Wrapper; str: Wrapper; }>'. str: inputs.num, // Causes error } } diff --git a/tests/baselines/reference/intraExpressionInferences.symbols b/tests/baselines/reference/intraExpressionInferences.symbols index f0a01515373d5..6f06adb8f294f 100644 --- a/tests/baselines/reference/intraExpressionInferences.symbols +++ b/tests/baselines/reference/intraExpressionInferences.symbols @@ -397,9 +397,7 @@ createMappingComponent({ str: inputs.num, // Causes error >str : Symbol(str, Decl(intraExpressionInferences.ts, 132, 37)) ->inputs.num : Symbol(num, Decl(intraExpressionInferences.ts, 120, 21)) >inputs : Symbol(inputs, Decl(intraExpressionInferences.ts, 130, 8)) ->num : Symbol(num, Decl(intraExpressionInferences.ts, 120, 21)) } } }); diff --git a/tests/baselines/reference/intraExpressionInferences.types b/tests/baselines/reference/intraExpressionInferences.types index e38c271c8614a..4832a03304796 100644 --- a/tests/baselines/reference/intraExpressionInferences.types +++ b/tests/baselines/reference/intraExpressionInferences.types @@ -361,7 +361,7 @@ declare function createMappingComponentcreateMappingComponent({ setup() { return { inputs: { num: new Wrapper(), str: new Wrapper() }, outputs: { bool: new Wrapper(), str: new Wrapper() } }; }, map(inputs) { return { bool: inputs.nonexistent, str: inputs.num, // Causes error } }}) : void >createMappingComponent : (def: MappingComponent) => void ->{ setup() { return { inputs: { num: new Wrapper(), str: new Wrapper() }, outputs: { bool: new Wrapper(), str: new Wrapper() } }; }, map(inputs) { return { bool: inputs.nonexistent, str: inputs.num, // Causes error } }} : { setup(): { inputs: { num: Wrapper; str: Wrapper; }; outputs: { bool: Wrapper; str: Wrapper; }; }; map(inputs: Unwrap<{ num: Wrapper; str: Wrapper; }>): { bool: any; str: number; }; } +>{ setup() { return { inputs: { num: new Wrapper(), str: new Wrapper() }, outputs: { bool: new Wrapper(), str: new Wrapper() } }; }, map(inputs) { return { bool: inputs.nonexistent, str: inputs.num, // Causes error } }} : { setup(): { inputs: { num: Wrapper; str: Wrapper; }; outputs: { bool: Wrapper; str: Wrapper; }; }; map(inputs: Unwrap): { bool: any; str: any; }; } setup() { >setup : () => { inputs: { num: Wrapper; str: Wrapper; }; outputs: { bool: Wrapper; str: Wrapper; }; } @@ -401,23 +401,23 @@ createMappingComponent({ }; }, map(inputs) { ->map : (inputs: Unwrap<{ num: Wrapper; str: Wrapper; }>) => { bool: any; str: number; } ->inputs : Unwrap<{ num: Wrapper; str: Wrapper; }> +>map : (inputs: Unwrap) => { bool: any; str: any; } +>inputs : Unwrap return { ->{ bool: inputs.nonexistent, str: inputs.num, // Causes error } : { bool: any; str: number; } +>{ bool: inputs.nonexistent, str: inputs.num, // Causes error } : { bool: any; str: any; } bool: inputs.nonexistent, >bool : any >inputs.nonexistent : any ->inputs : Unwrap<{ num: Wrapper; str: Wrapper; }> +>inputs : Unwrap >nonexistent : any str: inputs.num, // Causes error ->str : number ->inputs.num : number ->inputs : Unwrap<{ num: Wrapper; str: Wrapper; }> ->num : number +>str : any +>inputs.num : any +>inputs : Unwrap +>num : any } } }); diff --git a/tests/baselines/reference/iteratorSpreadInArray6.errors.txt b/tests/baselines/reference/iteratorSpreadInArray6.errors.txt index 03db7e32b3354..310b446568df9 100644 --- a/tests/baselines/reference/iteratorSpreadInArray6.errors.txt +++ b/tests/baselines/reference/iteratorSpreadInArray6.errors.txt @@ -7,6 +7,9 @@ iteratorSpreadInArray6.ts(15,14): error TS2769: No overload matches this call. Overload 2 of 2, '(...items: (number | ConcatArray)[]): number[]', gave the following error. Argument of type 'symbol[]' is not assignable to parameter of type 'number | ConcatArray'. Type 'symbol[]' is not assignable to type 'ConcatArray'. + The types returned by 'slice(...)' are incompatible between these types. + Type 'symbol[]' is not assignable to type 'number[]'. + Type 'symbol' is not assignable to type 'number'. ==== iteratorSpreadInArray6.ts (1 errors) ==== @@ -34,4 +37,7 @@ iteratorSpreadInArray6.ts(15,14): error TS2769: No overload matches this call. !!! error TS2769: Type 'symbol' is not assignable to type 'number'. !!! error TS2769: Overload 2 of 2, '(...items: (number | ConcatArray)[]): number[]', gave the following error. !!! error TS2769: Argument of type 'symbol[]' is not assignable to parameter of type 'number | ConcatArray'. -!!! error TS2769: Type 'symbol[]' is not assignable to type 'ConcatArray'. \ No newline at end of file +!!! error TS2769: Type 'symbol[]' is not assignable to type 'ConcatArray'. +!!! error TS2769: The types returned by 'slice(...)' are incompatible between these types. +!!! error TS2769: Type 'symbol[]' is not assignable to type 'number[]'. +!!! error TS2769: Type 'symbol' is not assignable to type 'number'. \ No newline at end of file diff --git a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt index e19b848ab74b1..485f87a7f8732 100644 --- a/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt +++ b/tests/baselines/reference/keyofAndIndexedAccessErrors.errors.txt @@ -22,6 +22,7 @@ keyofAndIndexedAccessErrors.ts(64,33): error TS2345: Argument of type '"name" | Type '"size"' is not assignable to type 'keyof Shape'. keyofAndIndexedAccessErrors.ts(66,24): error TS2345: Argument of type '"size"' is not assignable to parameter of type 'keyof Shape'. keyofAndIndexedAccessErrors.ts(67,24): error TS2345: Argument of type '"name" | "size"' is not assignable to parameter of type 'keyof Shape'. + Type '"size"' is not assignable to type 'keyof Shape'. keyofAndIndexedAccessErrors.ts(73,5): error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'. keyofAndIndexedAccessErrors.ts(74,5): error TS2536: Type 'keyof T | keyof U' cannot be used to index type 'T | U'. keyofAndIndexedAccessErrors.ts(82,5): error TS2322: Type 'keyof T | keyof U' is not assignable to type 'keyof T & keyof U'. @@ -184,6 +185,7 @@ keyofAndIndexedAccessErrors.ts(165,5): error TS2322: Type 'number' is not assign setProperty(shape, cond ? "name" : "size", 10); // Error ~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '"name" | "size"' is not assignable to parameter of type 'keyof Shape'. +!!! error TS2345: Type '"size"' is not assignable to type 'keyof Shape'. } function f20(x: T | U, y: T & U, k1: keyof (T | U), k2: keyof T & keyof U, k3: keyof (T & U), k4: keyof T | keyof U) { diff --git a/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.errors.txt b/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.errors.txt index 98137ac6dc931..488e2bb92db12 100644 --- a/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.errors.txt +++ b/tests/baselines/reference/overloadresolutionWithConstraintCheckingDeferred.errors.txt @@ -3,6 +3,7 @@ overloadresolutionWithConstraintCheckingDeferred.ts(14,37): error TS2345: Argume Property 'x' is missing in type 'C' but required in type 'A'. overloadresolutionWithConstraintCheckingDeferred.ts(16,5): error TS2322: Type 'string' is not assignable to type 'number'. overloadresolutionWithConstraintCheckingDeferred.ts(16,38): error TS2344: Type 'C' does not satisfy the constraint 'A'. + Property 'x' is missing in type 'C' but required in type 'A'. overloadresolutionWithConstraintCheckingDeferred.ts(19,14): error TS2344: Type 'C' does not satisfy the constraint 'A'. @@ -33,6 +34,8 @@ overloadresolutionWithConstraintCheckingDeferred.ts(19,14): error TS2344: Type ' !!! error TS2322: Type 'string' is not assignable to type 'number'. ~~~~~~~~ !!! error TS2344: Type 'C' does not satisfy the constraint 'A'. +!!! error TS2344: Property 'x' is missing in type 'C' but required in type 'A'. +!!! related TS2728 overloadresolutionWithConstraintCheckingDeferred.ts:1:15: 'x' is declared here. var result3: string = foo(x => { // x has type D var y: G; // error that D does not satisfy constraint, y is of type G, entire call to foo is an error diff --git a/tests/baselines/reference/overloadsWithProvisionalErrors.types b/tests/baselines/reference/overloadsWithProvisionalErrors.types index 359f15b626c21..2a14c1ebc497e 100644 --- a/tests/baselines/reference/overloadsWithProvisionalErrors.types +++ b/tests/baselines/reference/overloadsWithProvisionalErrors.types @@ -18,8 +18,8 @@ var func: { func(s => ({})); // Error for no applicable overload (object type is missing a and b) >func(s => ({})) : never >func : { (s: string): number; (lambda: (s: string) => { a: number; b: number; }): string; } ->s => ({}) : (s: any) => {} ->s : any +>s => ({}) : (s: string) => {} +>s : string >({}) : {} >{} : {} @@ -38,8 +38,8 @@ func(s => ({ a: blah, b: 3 })); // Only error inside the function, but not outsi func(s => ({ a: blah })); // Two errors here, one for blah not being defined, and one for the overload since it would not be applicable anyway >func(s => ({ a: blah })) : never >func : { (s: string): number; (lambda: (s: string) => { a: number; b: number; }): string; } ->s => ({ a: blah }) : (s: any) => { a: any; } ->s : any +>s => ({ a: blah }) : (s: string) => { a: any; } +>s : string >({ a: blah }) : { a: any; } >{ a: blah } : { a: any; } >a : any diff --git a/tests/baselines/reference/promisePermutations.errors.txt b/tests/baselines/reference/promisePermutations.errors.txt index 55ac1623cccbd..ea1a007e7c8d2 100644 --- a/tests/baselines/reference/promisePermutations.errors.txt +++ b/tests/baselines/reference/promisePermutations.errors.txt @@ -63,6 +63,8 @@ promisePermutations.ts(106,19): error TS2769: No overload matches this call. promisePermutations.ts(109,19): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(cb: (a: T) => T) => IPromise' is not assignable to parameter of type '(value: string) => IPromise'. + Types of parameters 'cb' and 'value' are incompatible. + Type 'string' is not assignable to type '(a: T) => T'. promisePermutations.ts(110,19): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(cb: (a: T) => T) => Promise' is not assignable to parameter of type '(value: string) => Promise'. @@ -114,9 +116,12 @@ promisePermutations.ts(137,33): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. Type 'IPromise' is not assignable to type 'IPromise'. + Type 'string' is not assignable to type 'number'. promisePermutations.ts(144,35): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. + Type 'string' is not assignable to type 'number'. promisePermutations.ts(152,36): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. @@ -130,6 +135,7 @@ promisePermutations.ts(158,21): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '{ (x: number): IPromise; (x: string): IPromise; }' is not assignable to parameter of type '(value: number) => IPromise'. Type 'IPromise' is not assignable to type 'IPromise'. + Type 'number' is not assignable to type 'string'. promisePermutations.ts(159,21): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '{ (x: number): Promise; (x: string): Promise; }' is not assignable to parameter of type '(value: number) => Promise'. @@ -350,6 +356,8 @@ promisePermutations.ts(160,21): error TS2769: No overload matches this call. !!! error TS2769: No overload matches this call. !!! error TS2769: The last overload gave the following error. !!! error TS2769: Argument of type '(cb: (a: T) => T) => IPromise' is not assignable to parameter of type '(value: string) => IPromise'. +!!! error TS2769: Types of parameters 'cb' and 'value' are incompatible. +!!! error TS2769: Type 'string' is not assignable to type '(a: T) => T'. !!! related TS2771 promisePermutations.ts:13:5: The last overload is declared here. var s7b = r7.then(testFunction7P, testFunction7P, testFunction7P); // error ~~~~~~~~~~~~~~ @@ -453,6 +461,7 @@ promisePermutations.ts(160,21): error TS2769: No overload matches this call. !!! error TS2769: The last overload gave the following error. !!! error TS2769: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. !!! error TS2769: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2769: Type 'string' is not assignable to type 'number'. !!! related TS2771 promisePermutations.ts:5:5: The last overload is declared here. var s9g = s9.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok @@ -465,6 +474,8 @@ promisePermutations.ts(160,21): error TS2769: No overload matches this call. !!! error TS2769: No overload matches this call. !!! error TS2769: The last overload gave the following error. !!! error TS2769: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2769: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2769: Type 'string' is not assignable to type 'number'. !!! related TS2771 promisePermutations.ts:13:5: The last overload is declared here. var r10e = r10.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s10 = testFunction10P(x => x); @@ -499,6 +510,7 @@ promisePermutations.ts(160,21): error TS2769: No overload matches this call. !!! error TS2769: The last overload gave the following error. !!! error TS2769: Argument of type '{ (x: number): IPromise; (x: string): IPromise; }' is not assignable to parameter of type '(value: number) => IPromise'. !!! error TS2769: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2769: Type 'number' is not assignable to type 'string'. !!! related TS2771 promisePermutations.ts:5:5: The last overload is declared here. var s11b = s11.then(testFunction11P, testFunction11P, testFunction11P); // error ~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/promisePermutations2.errors.txt b/tests/baselines/reference/promisePermutations2.errors.txt index 87559b404a648..c9840881c94e2 100644 --- a/tests/baselines/reference/promisePermutations2.errors.txt +++ b/tests/baselines/reference/promisePermutations2.errors.txt @@ -43,6 +43,8 @@ promisePermutations2.ts(105,19): error TS2769: No overload matches this call. promisePermutations2.ts(108,19): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(cb: (a: T) => T) => IPromise' is not assignable to parameter of type '(value: string) => IPromise'. + Types of parameters 'cb' and 'value' are incompatible. + Type 'string' is not assignable to type '(a: T) => T'. promisePermutations2.ts(109,19): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(cb: (a: T) => T) => Promise' is not assignable to parameter of type '(value: string) => Promise'. @@ -80,9 +82,12 @@ promisePermutations2.ts(133,19): error TS2345: Argument of type '(x: T, cb: < Target signature provides too few arguments. Expected 2 or more, but got 1. promisePermutations2.ts(136,33): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. Type 'IPromise' is not assignable to type 'IPromise'. + Type 'string' is not assignable to type 'number'. promisePermutations2.ts(143,35): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. + Type 'string' is not assignable to type 'number'. promisePermutations2.ts(151,36): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. Property 'catch' is missing in type 'IPromise' but required in type 'Promise'. promisePermutations2.ts(155,21): error TS2769: No overload matches this call. @@ -92,6 +97,7 @@ promisePermutations2.ts(155,21): error TS2769: No overload matches this call. Type 'number' is not assignable to type 'string'. promisePermutations2.ts(157,21): error TS2345: Argument of type '{ (x: number): IPromise; (x: string): IPromise; }' is not assignable to parameter of type '(value: number) => IPromise'. Type 'IPromise' is not assignable to type 'IPromise'. + Type 'number' is not assignable to type 'string'. promisePermutations2.ts(158,21): error TS2345: Argument of type '{ (x: number): Promise; (x: string): Promise; }' is not assignable to parameter of type '(value: number) => Promise'. Type 'Promise' is not assignable to type 'Promise'. Type 'number' is not assignable to type 'string'. @@ -277,6 +283,8 @@ promisePermutations2.ts(159,21): error TS2345: Argument of type '{ (x: number): !!! error TS2769: No overload matches this call. !!! error TS2769: The last overload gave the following error. !!! error TS2769: Argument of type '(cb: (a: T) => T) => IPromise' is not assignable to parameter of type '(value: string) => IPromise'. +!!! error TS2769: Types of parameters 'cb' and 'value' are incompatible. +!!! error TS2769: Type 'string' is not assignable to type '(a: T) => T'. !!! related TS2771 promisePermutations2.ts:12:5: The last overload is declared here. var s7b = r7.then(testFunction7P, testFunction7P, testFunction7P); // error ~~~~~~~~~~~~~~ @@ -360,6 +368,7 @@ promisePermutations2.ts(159,21): error TS2345: Argument of type '{ (x: number): ~~~~~~~~~ !!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. !!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2345: Type 'string' is not assignable to type 'number'. var s9g = s9.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var r10 = testFunction10(x => x); @@ -371,6 +380,8 @@ promisePermutations2.ts(159,21): error TS2345: Argument of type '{ (x: number): !!! error TS2769: No overload matches this call. !!! error TS2769: The last overload gave the following error. !!! error TS2769: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2769: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2769: Type 'string' is not assignable to type 'number'. !!! related TS2771 promisePermutations2.ts:12:5: The last overload is declared here. var r10e = r10.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s10 = testFunction10P(x => x); @@ -400,6 +411,7 @@ promisePermutations2.ts(159,21): error TS2345: Argument of type '{ (x: number): ~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '{ (x: number): IPromise; (x: string): IPromise; }' is not assignable to parameter of type '(value: number) => IPromise'. !!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. var s11b = s11.then(testFunction11P, testFunction11P, testFunction11P); // ok ~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '{ (x: number): Promise; (x: string): Promise; }' is not assignable to parameter of type '(value: number) => Promise'. diff --git a/tests/baselines/reference/promisePermutations3.errors.txt b/tests/baselines/reference/promisePermutations3.errors.txt index 4b653256db3e7..e3967f6750a04 100644 --- a/tests/baselines/reference/promisePermutations3.errors.txt +++ b/tests/baselines/reference/promisePermutations3.errors.txt @@ -56,6 +56,8 @@ promisePermutations3.ts(105,19): error TS2345: Argument of type '(cb: (a: T) Types of parameters 'cb' and 'value' are incompatible. Type 'string' is not assignable to type '(a: T) => T'. promisePermutations3.ts(108,19): error TS2345: Argument of type '(cb: (a: T) => T) => IPromise' is not assignable to parameter of type '(value: string) => IPromise'. + Types of parameters 'cb' and 'value' are incompatible. + Type 'string' is not assignable to type '(a: T) => T'. promisePermutations3.ts(109,19): error TS2345: Argument of type '(cb: (a: T) => T) => Promise' is not assignable to parameter of type '(value: string) => Promise'. Types of parameters 'cb' and 'value' are incompatible. Type 'string' is not assignable to type '(a: T) => T'. @@ -97,7 +99,10 @@ promisePermutations3.ts(136,33): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. Type 'IPromise' is not assignable to type 'IPromise'. + Type 'string' is not assignable to type 'number'. promisePermutations3.ts(143,35): error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. + Type 'IPromise' is not assignable to type 'IPromise'. + Type 'string' is not assignable to type 'number'. promisePermutations3.ts(151,36): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => Promise'. @@ -109,6 +114,7 @@ promisePermutations3.ts(157,21): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '{ (x: number): IPromise; (x: string): IPromise; }' is not assignable to parameter of type '(value: number) => IPromise'. Type 'IPromise' is not assignable to type 'IPromise'. + Type 'number' is not assignable to type 'string'. promisePermutations3.ts(158,21): error TS2769: No overload matches this call. The last overload gave the following error. Argument of type '{ (x: number): Promise; (x: string): Promise; }' is not assignable to parameter of type '(value: number) => Promise'. @@ -320,6 +326,8 @@ promisePermutations3.ts(165,21): error TS2345: Argument of type '{ (x: T): IP var s7a = r7.then(testFunction7, testFunction7, testFunction7); // error ~~~~~~~~~~~~~ !!! error TS2345: Argument of type '(cb: (a: T) => T) => IPromise' is not assignable to parameter of type '(value: string) => IPromise'. +!!! error TS2345: Types of parameters 'cb' and 'value' are incompatible. +!!! error TS2345: Type 'string' is not assignable to type '(a: T) => T'. var s7b = r7.then(testFunction7P, testFunction7P, testFunction7P); // error ~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '(cb: (a: T) => T) => Promise' is not assignable to parameter of type '(value: string) => Promise'. @@ -407,6 +415,7 @@ promisePermutations3.ts(165,21): error TS2345: Argument of type '{ (x: T): IP !!! error TS2769: The last overload gave the following error. !!! error TS2769: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. !!! error TS2769: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2769: Type 'string' is not assignable to type 'number'. !!! related TS2771 promisePermutations3.ts:7:5: The last overload is declared here. var s9g = s9.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok @@ -417,6 +426,8 @@ promisePermutations3.ts(165,21): error TS2345: Argument of type '{ (x: T): IP var r10d = r10.then(testFunction, sIPromise, nIPromise); // error ~~~~~~~~~ !!! error TS2345: Argument of type '(x: any) => IPromise' is not assignable to parameter of type '(error: any) => IPromise'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2345: Type 'string' is not assignable to type 'number'. var r10e = r10.then(testFunction, nIPromise, sIPromise).then(sIPromise, sIPromise, sIPromise); // ok var s10 = testFunction10P(x => x); var s10a = s10.then(testFunction10, testFunction10, testFunction10); // ok @@ -447,6 +458,7 @@ promisePermutations3.ts(165,21): error TS2345: Argument of type '{ (x: T): IP !!! error TS2769: The last overload gave the following error. !!! error TS2769: Argument of type '{ (x: number): IPromise; (x: string): IPromise; }' is not assignable to parameter of type '(value: number) => IPromise'. !!! error TS2769: Type 'IPromise' is not assignable to type 'IPromise'. +!!! error TS2769: Type 'number' is not assignable to type 'string'. !!! related TS2771 promisePermutations3.ts:7:5: The last overload is declared here. var s11b = s11.then(testFunction11P, testFunction11P, testFunction11P); // error ~~~~~~~~~~~~~~~ diff --git a/tests/baselines/reference/reactDefaultPropsInferenceSuccess.errors.txt b/tests/baselines/reference/reactDefaultPropsInferenceSuccess.errors.txt index b3d8cecc8c1fa..8d798bc537fef 100644 --- a/tests/baselines/reference/reactDefaultPropsInferenceSuccess.errors.txt +++ b/tests/baselines/reference/reactDefaultPropsInferenceSuccess.errors.txt @@ -5,6 +5,8 @@ reactDefaultPropsInferenceSuccess.tsx(27,36): error TS2769: No overload matches Type 'void' is not assignable to type 'boolean'. Overload 2 of 2, '(props: Props, context?: any): FieldFeedback', gave the following error. Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. + Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. + Type 'void' is not assignable to type 'boolean'. reactDefaultPropsInferenceSuccess.tsx(43,41): error TS2769: No overload matches this call. Overload 1 of 2, '(props: Readonly): FieldFeedbackBeta', gave the following error. Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. @@ -12,12 +14,15 @@ reactDefaultPropsInferenceSuccess.tsx(43,41): error TS2769: No overload matches Type 'void' is not assignable to type 'boolean'. Overload 2 of 2, '(props: Props, context?: any): FieldFeedbackBeta', gave the following error. Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. + Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. + Type 'void' is not assignable to type 'boolean'. reactDefaultPropsInferenceSuccess.tsx(64,37): error TS2769: No overload matches this call. Overload 1 of 2, '(props: Readonly): FieldFeedback2', gave the following error. Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. Type 'void' is not assignable to type 'boolean'. Overload 2 of 2, '(props: MyPropsProps, context?: any): FieldFeedback2', gave the following error. Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. + Type 'void' is not assignable to type 'boolean'. ==== reactDefaultPropsInferenceSuccess.tsx (3 errors) ==== @@ -56,6 +61,8 @@ reactDefaultPropsInferenceSuccess.tsx(64,37): error TS2769: No overload matches !!! error TS2769: Type 'void' is not assignable to type 'boolean'. !!! error TS2769: Overload 2 of 2, '(props: Props, context?: any): FieldFeedback', gave the following error. !!! error TS2769: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. +!!! error TS2769: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. +!!! error TS2769: Type 'void' is not assignable to type 'boolean'. !!! related TS6500 reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children" | "error"> & Partial & Readonly, "when">> & Partial boolean; }, never>>' !!! related TS6500 reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children" | "error"> & Partial & Readonly, "when">> & Partial boolean; }, never>>' @@ -82,6 +89,8 @@ reactDefaultPropsInferenceSuccess.tsx(64,37): error TS2769: No overload matches !!! error TS2769: Type 'void' is not assignable to type 'boolean'. !!! error TS2769: Overload 2 of 2, '(props: Props, context?: any): FieldFeedbackBeta', gave the following error. !!! error TS2769: Type '(value: string) => void' is not assignable to type '"a" | "b" | ((value: string) => boolean) | undefined'. +!!! error TS2769: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. +!!! error TS2769: Type 'void' is not assignable to type 'boolean'. !!! related TS6500 reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children"> & Partial & Readonly, keyof Props>> & Partial>' !!! related TS6500 reactDefaultPropsInferenceSuccess.tsx:6:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children"> & Partial & Readonly, keyof Props>> & Partial>' @@ -112,6 +121,7 @@ reactDefaultPropsInferenceSuccess.tsx(64,37): error TS2769: No overload matches !!! error TS2769: Type 'void' is not assignable to type 'boolean'. !!! error TS2769: Overload 2 of 2, '(props: MyPropsProps, context?: any): FieldFeedback2', gave the following error. !!! error TS2769: Type '(value: string) => void' is not assignable to type '(value: string) => boolean'. +!!! error TS2769: Type 'void' is not assignable to type 'boolean'. !!! related TS6500 reactDefaultPropsInferenceSuccess.tsx:46:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children" | "error"> & Partial & Readonly, "when">> & Partial boolean; }, never>>' !!! related TS6500 reactDefaultPropsInferenceSuccess.tsx:46:3: The expected type comes from property 'when' which is declared here on type 'IntrinsicAttributes & IntrinsicClassAttributes> & Pick & Readonly, "children" | "error"> & Partial & Readonly, "when">> & Partial boolean; }, never>>' diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1.errors.txt b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1.errors.txt index b9eb286af2ff8..4ebe0dd9bd58f 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1.errors.txt +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1.errors.txt @@ -1,21 +1,28 @@ taggedTemplateStringsWithOverloadResolution1.ts(9,13): error TS2345: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. taggedTemplateStringsWithOverloadResolution1.ts(10,13): error TS2345: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. taggedTemplateStringsWithOverloadResolution1.ts(11,13): error TS2769: No overload matches this call. Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. taggedTemplateStringsWithOverloadResolution1.ts(12,13): error TS2769: No overload matches this call. Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. taggedTemplateStringsWithOverloadResolution1.ts(13,13): error TS2769: No overload matches this call. Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. taggedTemplateStringsWithOverloadResolution1.ts(14,23): error TS2554: Expected 1-3 arguments, but got 4. taggedTemplateStringsWithOverloadResolution1.ts(19,20): error TS2769: No overload matches this call. Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. @@ -43,30 +50,44 @@ taggedTemplateStringsWithOverloadResolution1.ts(21,24): error TS2554: Expected 1 var b = foo([], 1); // string ~~ !!! error TS2345: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2345: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. !!! related TS2793 taggedTemplateStringsWithOverloadResolution1.ts:5:10: The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible. var c = foo([], 1, 2); // boolean ~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. !!! error TS2769: Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. !!! related TS2793 taggedTemplateStringsWithOverloadResolution1.ts:5:10: The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible. var d = foo([], 1, true); // boolean (with error) ~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. !!! error TS2769: Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. !!! related TS2793 taggedTemplateStringsWithOverloadResolution1.ts:5:10: The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible. var e = foo([], 1, "2"); // {} ~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. !!! error TS2769: Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. !!! related TS2793 taggedTemplateStringsWithOverloadResolution1.ts:5:10: The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible. var f = foo([], 1, 2, 3); // any (with error) ~ diff --git a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.errors.txt b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.errors.txt index 1db36713d9cea..128b830203eba 100644 --- a/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.errors.txt +++ b/tests/baselines/reference/taggedTemplateStringsWithOverloadResolution1_ES6.errors.txt @@ -1,21 +1,28 @@ taggedTemplateStringsWithOverloadResolution1_ES6.ts(9,13): error TS2345: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. taggedTemplateStringsWithOverloadResolution1_ES6.ts(10,13): error TS2345: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. taggedTemplateStringsWithOverloadResolution1_ES6.ts(11,13): error TS2769: No overload matches this call. Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. taggedTemplateStringsWithOverloadResolution1_ES6.ts(12,13): error TS2769: No overload matches this call. Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. taggedTemplateStringsWithOverloadResolution1_ES6.ts(13,13): error TS2769: No overload matches this call. Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. + Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. taggedTemplateStringsWithOverloadResolution1_ES6.ts(14,23): error TS2554: Expected 1-3 arguments, but got 4. taggedTemplateStringsWithOverloadResolution1_ES6.ts(19,20): error TS2769: No overload matches this call. Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. @@ -43,30 +50,44 @@ taggedTemplateStringsWithOverloadResolution1_ES6.ts(21,24): error TS2554: Expect var b = foo([], 1); // string ~~ !!! error TS2345: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2345: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. !!! related TS2793 taggedTemplateStringsWithOverloadResolution1_ES6.ts:5:10: The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible. var c = foo([], 1, 2); // boolean ~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. !!! error TS2769: Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. !!! related TS2793 taggedTemplateStringsWithOverloadResolution1_ES6.ts:5:10: The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible. var d = foo([], 1, true); // boolean (with error) ~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. !!! error TS2769: Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. !!! related TS2793 taggedTemplateStringsWithOverloadResolution1_ES6.ts:5:10: The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible. var e = foo([], 1, "2"); // {} ~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 4, '(strs: TemplateStringsArray, x: number, y: number): boolean', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. !!! error TS2769: Overload 2 of 4, '(strs: TemplateStringsArray, x: number, y: string): {}', gave the following error. !!! error TS2769: Argument of type 'undefined[]' is not assignable to parameter of type 'TemplateStringsArray'. +!!! error TS2769: Property 'raw' is missing in type 'undefined[]' but required in type 'TemplateStringsArray'. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. +!!! related TS2728 lib.es5.d.ts:--:--: 'raw' is declared here. !!! related TS2793 taggedTemplateStringsWithOverloadResolution1_ES6.ts:5:10: The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible. var f = foo([], 1, 2, 3); // any (with error) ~ diff --git a/tests/baselines/reference/tsc/incremental/serializing-error-chains.js b/tests/baselines/reference/tsc/incremental/serializing-error-chains.js index 482eed6921854..6cc36f1c621e7 100644 --- a/tests/baselines/reference/tsc/incremental/serializing-error-chains.js +++ b/tests/baselines/reference/tsc/incremental/serializing-error-chains.js @@ -45,26 +45,18 @@ declare function Component(props: { children?: number }): any; Output:: /lib/tsc -p src/project -src/project/index.tsx:10:3 - error TS2746: This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided. - -10 ( -   ~~~~~~~~~ - -src/project/index.tsx:10:3 - error TS2746: This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided. - -10 ( -   ~~~~~~~~~ - src/project/index.tsx:10:3 - error TS2769: No overload matches this call. - This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided. - This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided. + Overload 1 of 2, '(props: never): any', gave the following error. + This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided. + Overload 2 of 2, '(props: { children?: number | undefined; }): any', gave the following error. + This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided. 10 (    ~~~~~~~~~ -Found 3 errors in the same file, starting at: src/project/index.tsx:10 +Found 1 error in src/project/index.tsx:10 exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated @@ -77,7 +69,7 @@ exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated //// [/src/project/tsconfig.tsbuildinfo] -{"program":{"fileNames":["../../lib/lib.d.ts","./index.tsx"],"fileInfos":[{"version":"7198220534-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };\ninterface ReadonlyArray { readonly length: number }","affectsGlobalScope":true},{"version":"42569361247-declare namespace JSX {\n interface ElementChildrenAttribute { children: {}; }\n interface IntrinsicElements { div: {} }\n}\n\ndeclare var React: any;\n\ndeclare function Component(props: never): any;\ndeclare function Component(props: { children?: number }): any;\n(\n
\n
\n)","affectsGlobalScope":true}],"root":[2],"options":{"jsx":2,"module":99,"strict":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,[2,[{"file":"./index.tsx","start":265,"length":9,"messageText":"This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided.","category":1,"code":2746},{"file":"./index.tsx","start":265,"length":9,"messageText":"This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided.","category":1,"code":2746},{"file":"./index.tsx","start":265,"length":9,"code":2769,"category":1,"messageText":{"messageText":"No overload matches this call.","category":1,"code":2769,"next":[{"code":2746,"category":1,"messageText":"This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided."},{"code":2746,"category":1,"messageText":"This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided."}]},"relatedInformation":[]}]]]},"version":"FakeTSVersion"} +{"program":{"fileNames":["../../lib/lib.d.ts","./index.tsx"],"fileInfos":[{"version":"7198220534-/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }\ninterface ReadonlyArray {}\ndeclare const console: { log(msg: any): void; };\ninterface ReadonlyArray { readonly length: number }","affectsGlobalScope":true},{"version":"42569361247-declare namespace JSX {\n interface ElementChildrenAttribute { children: {}; }\n interface IntrinsicElements { div: {} }\n}\n\ndeclare var React: any;\n\ndeclare function Component(props: never): any;\ndeclare function Component(props: { children?: number }): any;\n(\n
\n
\n)","affectsGlobalScope":true}],"root":[2],"options":{"jsx":2,"module":99,"strict":true},"referencedMap":[],"exportedModulesMap":[],"semanticDiagnosticsPerFile":[1,[2,[{"file":"./index.tsx","start":265,"length":9,"code":2769,"category":1,"messageText":{"messageText":"No overload matches this call.","category":1,"code":2769,"next":[{"messageText":"Overload 1 of 2, '(props: never): any', gave the following error.","category":1,"code":2772,"next":[{"code":2746,"category":1,"messageText":"This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided."}]},{"messageText":"Overload 2 of 2, '(props: { children?: number | undefined; }): any', gave the following error.","category":1,"code":2772,"next":[{"code":2746,"category":1,"messageText":"This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided."}]}]},"relatedInformation":[]}]]]},"version":"FakeTSVersion"} //// [/src/project/tsconfig.tsbuildinfo.readable.baseline.txt] { @@ -124,22 +116,6 @@ exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated [ "./index.tsx", [ - { - "file": "./index.tsx", - "start": 265, - "length": 9, - "messageText": "This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided.", - "category": 1, - "code": 2746 - }, - { - "file": "./index.tsx", - "start": 265, - "length": 9, - "messageText": "This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided.", - "category": 1, - "code": 2746 - }, { "file": "./index.tsx", "start": 265, @@ -152,14 +128,28 @@ exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated "code": 2769, "next": [ { - "code": 2746, + "messageText": "Overload 1 of 2, '(props: never): any', gave the following error.", "category": 1, - "messageText": "This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided." + "code": 2772, + "next": [ + { + "code": 2746, + "category": 1, + "messageText": "This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided." + } + ] }, { - "code": 2746, + "messageText": "Overload 2 of 2, '(props: { children?: number | undefined; }): any', gave the following error.", "category": 1, - "messageText": "This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided." + "code": 2772, + "next": [ + { + "code": 2746, + "category": 1, + "messageText": "This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided." + } + ] } ] }, @@ -170,7 +160,7 @@ exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated ] }, "version": "FakeTSVersion", - "size": 2064 + "size": 1926 } @@ -181,26 +171,18 @@ Input:: Output:: /lib/tsc -p src/project -src/project/index.tsx:10:3 - error TS2746: This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided. - -10 ( -   ~~~~~~~~~ - -src/project/index.tsx:10:3 - error TS2746: This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided. - -10 ( -   ~~~~~~~~~ - src/project/index.tsx:10:3 - error TS2769: No overload matches this call. - This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided. - This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided. + Overload 1 of 2, '(props: never): any', gave the following error. + This JSX tag's 'children' prop expects a single child of type 'never', but multiple children were provided. + Overload 2 of 2, '(props: { children?: number | undefined; }): any', gave the following error. + This JSX tag's 'children' prop expects a single child of type 'number | undefined', but multiple children were provided. 10 (    ~~~~~~~~~ -Found 3 errors in the same file, starting at: src/project/index.tsx:10 +Found 1 error in src/project/index.tsx:10 exitCode:: ExitStatus.DiagnosticsPresent_OutputsGenerated diff --git a/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt b/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt index 33a85ca2e9951..5bd0a3bf13316 100644 --- a/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt +++ b/tests/baselines/reference/tsxNotUsingApparentTypeOfSFC.errors.txt @@ -13,6 +13,7 @@ tsxNotUsingApparentTypeOfSFC.tsx(18,14): error TS2769: No overload matches this Type 'P' is not assignable to type 'IntrinsicAttributes'. Overload 2 of 2, '(props: P, context?: any): MyComponent', gave the following error. Type 'P' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly<{ children?: ReactNode; }> & Readonly

'. + Type 'P' is not assignable to type 'IntrinsicAttributes'. ==== tsxNotUsingApparentTypeOfSFC.tsx (4 errors) ==== @@ -54,7 +55,9 @@ tsxNotUsingApparentTypeOfSFC.tsx(18,14): error TS2769: No overload matches this !!! error TS2769: Type 'P' is not assignable to type 'IntrinsicAttributes'. !!! error TS2769: Overload 2 of 2, '(props: P, context?: any): MyComponent', gave the following error. !!! error TS2769: Type 'P' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes & Readonly<{ children?: ReactNode; }> & Readonly

'. +!!! error TS2769: Type 'P' is not assignable to type 'IntrinsicAttributes'. !!! related TS2208 tsxNotUsingApparentTypeOfSFC.tsx:5:15: This type parameter might need an `extends JSX.IntrinsicAttributes` constraint. !!! related TS2208 tsxNotUsingApparentTypeOfSFC.tsx:5:15: This type parameter might need an `extends JSX.IntrinsicAttributes & JSX.IntrinsicClassAttributes & Readonly<{ children?: React.ReactNode; }> & Readonly

` constraint. +!!! related TS2208 tsxNotUsingApparentTypeOfSFC.tsx:5:15: This type parameter might need an `extends JSX.IntrinsicAttributes` constraint. !!! related TS2208 tsxNotUsingApparentTypeOfSFC.tsx:5:15: This type parameter might need an `extends JSX.IntrinsicAttributes & JSX.IntrinsicClassAttributes & Readonly<{ children?: React.ReactNode; }> & Readonly

` constraint. } \ No newline at end of file diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt index cf6aab23da1ff..fe264fff22813 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt @@ -3,10 +3,10 @@ file.tsx(48,13): error TS2769: No overload matches this call. Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'to' does not exist on type 'IntrinsicAttributes & ButtonProps'. Overload 2 of 3, '(linkProps: LinkProps): Element', gave the following error. - Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. + Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. Overload 3 of 3, '(hyphenProps: HyphenProps): Element', gave the following error. - Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. + Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. file.tsx(54,51): error TS2769: No overload matches this call. Overload 1 of 3, '(buttonProps: ButtonProps): Element', gave the following error. @@ -88,10 +88,10 @@ file.tsx(56,13): error TS2769: No overload matches this call. !!! error TS2769: Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. !!! error TS2769: Property 'to' does not exist on type 'IntrinsicAttributes & ButtonProps'. !!! error TS2769: Overload 2 of 3, '(linkProps: LinkProps): Element', gave the following error. -!!! error TS2769: Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. +!!! error TS2769: Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. !!! error TS2769: Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. !!! error TS2769: Overload 3 of 3, '(hyphenProps: HyphenProps): Element', gave the following error. -!!! error TS2769: Type '{ children: string; to: string; onClick: (e: MouseEvent) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2769: Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. !!! error TS2769: Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. !!! related TS2793 file.tsx:38:17: The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible. const b1 = {}} {...obj0}>Hello world; // extra property; diff --git a/tests/baselines/reference/unionThisTypeInFunctions.errors.txt b/tests/baselines/reference/unionThisTypeInFunctions.errors.txt index ac850453379bb..acaac604ccb9c 100644 --- a/tests/baselines/reference/unionThisTypeInFunctions.errors.txt +++ b/tests/baselines/reference/unionThisTypeInFunctions.errors.txt @@ -1,12 +1,8 @@ unionThisTypeInFunctions.ts(10,5): error TS2684: The 'this' context of type 'Real | Fake' is not assignable to method's 'this' of type 'Real & Fake'. Type 'Real' is not assignable to type 'Real & Fake'. Type 'Real' is not assignable to type 'Fake'. - Types of property 'method' are incompatible. - Type '(this: Real, n: number) => void' is not assignable to type '(this: Fake, n: number) => void'. - The 'this' types of each signature are incompatible. - Type 'Fake' is not assignable to type 'Real'. - Types of property 'data' are incompatible. - Type 'number' is not assignable to type 'string'. + Types of property 'data' are incompatible. + Type 'string' is not assignable to type 'number'. ==== unionThisTypeInFunctions.ts (1 errors) ==== @@ -24,11 +20,7 @@ unionThisTypeInFunctions.ts(10,5): error TS2684: The 'this' context of type 'Rea !!! error TS2684: The 'this' context of type 'Real | Fake' is not assignable to method's 'this' of type 'Real & Fake'. !!! error TS2684: Type 'Real' is not assignable to type 'Real & Fake'. !!! error TS2684: Type 'Real' is not assignable to type 'Fake'. -!!! error TS2684: Types of property 'method' are incompatible. -!!! error TS2684: Type '(this: Real, n: number) => void' is not assignable to type '(this: Fake, n: number) => void'. -!!! error TS2684: The 'this' types of each signature are incompatible. -!!! error TS2684: Type 'Fake' is not assignable to type 'Real'. -!!! error TS2684: Types of property 'data' are incompatible. -!!! error TS2684: Type 'number' is not assignable to type 'string'. +!!! error TS2684: Types of property 'data' are incompatible. +!!! error TS2684: Type 'string' is not assignable to type 'number'. } \ No newline at end of file From e861368c91927f72f207d0ee4b8a967d0ea906f0 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 29 Feb 2024 11:42:09 -0800 Subject: [PATCH 11/18] Accept positive baseline diff...? --- .../ramdaToolsNoInfinite2.errors.txt | 581 ------------------ 1 file changed, 581 deletions(-) delete mode 100644 tests/baselines/reference/ramdaToolsNoInfinite2.errors.txt diff --git a/tests/baselines/reference/ramdaToolsNoInfinite2.errors.txt b/tests/baselines/reference/ramdaToolsNoInfinite2.errors.txt deleted file mode 100644 index 0b66551b2f68b..0000000000000 --- a/tests/baselines/reference/ramdaToolsNoInfinite2.errors.txt +++ /dev/null @@ -1,581 +0,0 @@ -ramdaToolsNoInfinite2.ts(286,76): error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' does not satisfy the constraint 'List'. - Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' is missing the following properties from type 'readonly any[]': length, concat, join, slice, and 9 more. -ramdaToolsNoInfinite2.ts(327,90): error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' does not satisfy the constraint 'List'. - Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' is missing the following properties from type 'readonly any[]': length, concat, join, slice, and 9 more. - - -==== ramdaToolsNoInfinite2.ts (2 errors) ==== - declare module "Any/Kind" { - import { Extends } from "Any/Extends"; - import { List } from "List/List"; - - export type Kind = Extends extends 1 ? 'function' : Extends extends 1 ? 'array' : Extends extends 1 ? 'object' : Extends extends 1 ? 'string' : Extends extends 1 ? 'number' : Extends extends 1 ? 'boolean' : 'unknown'; - } - declare module "Any/Compute" { - export type Compute = A extends Function ? A : { - [K in keyof A]: A[K]; - } & {}; - } - declare module "Object/Pick" { - import { Key } from "Any/Key"; - - type __Pick = { - [P in K]: O[P]; - } & {}; - - export type _Pick = __Pick; - - export type Pick = O extends unknown ? _Pick : never; - } - declare module "Object/Keys" { - import { Keys as UKeys } from "Union/Keys"; - - export type Keys = UKeys; - } - declare module "Object/Omit" { - import { _Pick } from "Object/Pick"; - import { Exclude } from "Union/Exclude"; - import { Key } from "Any/Key"; - import { Keys } from "Object/Keys"; - export type _Omit = _Pick, K>>; - - export type Omit = O extends unknown ? _Omit : never; - } - declare module "Object/At" { - import { Key } from "Any/Key"; - import { Boolean } from "Boolean/Boolean"; - - type AtStrict = [K & keyof O] extends [never] ? never : O[K & keyof O]; - - type AtLoose = O extends unknown ? AtStrict : never; - - export type At = { - 1: AtStrict; - 0: AtLoose; - }[strict]; - } - declare module "Boolean/Boolean" { - export type Boolean = True | False; - - export type True = 1; - - export type False = 0; - } - declare module "Boolean/Not" { - import { Boolean } from "Boolean/Boolean"; - - export type Not = { - 0: 1; - 1: 0; - }[B]; - } - declare module "Union/Has" { - import { Union } from "Union/Union"; - import { Not } from "Boolean/Not"; - import { Extends } from "Any/Extends"; - - export type Has = Not, U1>>; - } - declare module "Union/Union" { - export type Union = any; - } - declare module "Union/Exclude" { - import { Union } from "Union/Union"; - - export type Exclude = U extends M ? never : U; - } - declare module "Any/_Internal" { - import { _NumberOf } from "Number/NumberOf"; - - export type Match = 'default' | 'implements->' | '<-implements' | 'extends->' | '<-extends' | 'equals'; - - export type NumberOf = N extends number ? _NumberOf : N; - } - declare module "Any/Implements" { - import { Extends } from "Any/Extends"; - - export type Implements = Extends extends 1 ? 1 : 0; - } - declare module "Any/Key" { - export type Key = string | number | symbol; - } - declare module "Union/Keys" { - import { Union } from "Union/Union"; - import { Key } from "Any/Key"; - - export type Keys = (U extends unknown ? keyof U : never) & Key; - } - declare module "List/ObjectOf" { - import { _Omit } from "Object/Omit"; - import { Has } from "Union/Has"; - import { At } from "Object/At"; - import { List } from "List/List"; - - export type _ObjectOf = Has extends 1 ? number extends At ? _Omit> : _Omit : L; - - export type ObjectOf = L extends unknown ? _ObjectOf : never; - } - declare module "List/Keys" { - import { Exclude } from "Union/Exclude"; - import { List } from "List/List"; - import { Keys as UKeys } from "Union/Keys"; - - export type Keys = Exclude, keyof any[]> | number; - } - declare module "Object/Merge" { - import { _Omit } from "Object/Omit"; - import { At } from "Object/At"; - import { Compute } from "Any/Compute"; - import { Depth } from "Object/_Internal"; - import { Kind } from "Any/Kind"; - - export type MergeFlat = Compute>; - - export type MergeDeep = (Kind<(O | O1)> extends 'object' ? MergeFlat extends infer M ? { - [K in keyof M]: MergeDeep>; - } & {} : never : O); - - export type Merge = { - 'flat': MergeFlat; - 'deep': MergeDeep; - }[depth]; - } - declare module "Union/NonNullable" { - import { Exclude } from "Union/Exclude"; - import { Union } from "Union/Union"; - - export type NonNullable = Exclude; - } - declare module "Object/ListOf" { - import { IterationOf } from "Iteration/IterationOf"; - import { Iteration } from "Iteration/Iteration"; - import { Cast } from "Any/Cast"; - import { Key } from "Iteration/Key"; - import { Next } from "Iteration/Next"; - import { _Append } from "List/Append"; - import { Exclude } from "Union/Exclude"; - import { List } from "List/List"; - import { Extends } from "Any/Extends"; - - type PickIfEntry = Key extends keyof O ? _Append, keyof O>]> : LN; - - type __ListOf> = { - 0: __ListOf>, PickIfEntry, Next>; - 1: LN; - }[Extends<[K], [never]>]; - - export type _ListOf = __ListOf extends infer X ? Cast : never; - - export type ListOf = O extends unknown ? _ListOf : never; - } - declare module "Object/NonNullable" { - import { MergeFlat } from "Object/Merge"; - import { NonNullable as UNonNullable } from "Union/NonNullable"; - import { Depth } from "Object/_Internal"; - import { Pick } from "Object/Pick"; - import { Key } from "Any/Key"; - import { Implements } from "Any/Implements"; - import { Keys } from "Object/Keys"; - - export type NonNullableFlat = { - [K in keyof O]: UNonNullable; - } & {}; - - export type NonNullableDeep = { - [K in keyof O]: NonNullableDeep>; - }; - - type NonNullablePart = { - 'flat': NonNullableFlat; - 'deep': NonNullableDeep; - }[depth]; - - export type NonNullable = { - 1: NonNullablePart; - 0: MergeFlat, depth>, O>; - }[Implements, K>] & {}; - } - declare module "Object/Overwrite" { - export type Overwrite = { - [K in keyof O]: K extends keyof O1 ? O1[K] : O[K]; - } & {}; - } - declare module "Number/_Internal" { - import { IterationMap } from "Iteration/IterationOf"; - import { Format } from "Iteration/Format"; - - export type Formats = 'b' | 'n' | 's'; - - type KnownIterationMapKeys = '-40' | '-39' | '-38' | '-37' | '-36' | '-35' | '-34' | '-33' | '-32' | '-31' | '-30' | '-29' | '-28' | '-27' | '-26' | '-25' | '-24' | '-23' | '-22' | '-21' | '-20' | '-19' | '-18' | '-17' | '-16' | '-15' | '-14' | '-13' | '-12' | '-11' | '-10' | '-9' | '-8' | '-7' | '-6' | '-5' | '-4' | '-3' | '-2' | '-1' | '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | '13' | '14' | '15' | '16' | '17' | '18' | '19' | '20' | '21' | '22' | '23' | '24' | '25' | '26' | '27' | '28' | '29' | '30' | '31' | '32' | '33' | '34' | '35' | '36' | '37' | '38' | '39' | '40'; - - type PositiveIterationKeys = '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' | '10' | '11' | '12' | '13' | '14' | '15' | '16' | '17' | '18' | '19' | '20' | '21' | '22' | '23' | '24' | '25' | '26' | '27' | '28' | '29' | '30' | '31' | '32' | '33' | '34' | '35' | '36' | '37' | '38' | '39' | '40'; - - type NegativeIterationKeys = '-40' | '-39' | '-38' | '-37' | '-36' | '-35' | '-34' | '-33' | '-32' | '-31' | '-30' | '-29' | '-28' | '-27' | '-26' | '-25' | '-24' | '-23' | '-22' | '-21' | '-20' | '-19' | '-18' | '-17' | '-16' | '-15' | '-14' | '-13' | '-12' | '-11' | '-10' | '-9' | '-8' | '-7' | '-6' | '-5' | '-4' | '-3' | '-2' | '-1'; - - export type Numbers = { - 'string': { - 'all': Format; - '+': Format; - '-': Format; - '0': Format; - }; - 'number': { - 'all': Format; - '+': Format; - '-': Format; - '0': Format; - }; - }; - } - declare module "Number/Number" { - export type Number = string; - } - declare module "Iteration/_Internal" { - export type Formats = 'n' | 's'; - export type Way = '->' | '<-'; - } - declare module "List/Prepend" { - import { List } from "List/List"; - - export type Prepend = ((head: A, ...args: L) => any) extends ((...args: infer U) => any) ? U : L; - } - declare module "List/_Internal" { - import { Overwrite } from "Object/Overwrite"; - import { List } from "List/List"; - - export type Naked = Overwrite, L>; - } - declare module "List/Tail" { - import { List } from "List/List"; - - export type Tail = ((...t: L) => any) extends ((head: any, ...tail: infer LTail) => any) ? LTail : never; - } - declare module "Iteration/Format" { - import { Iteration } from "Iteration/Iteration"; - import { Formats } from "Iteration/_Internal"; - - export type Format = { - 's': I[2]; - 'n': I[3]; - }[fmt]; - } - declare module "Iteration/Pos" { - import { Iteration } from "Iteration/Iteration"; - import { Format } from "Iteration/Format"; - - export type Pos = Format; - } - declare module "List/Append" { - import { _Concat } from "List/Concat"; - import { List } from "List/List"; - - export type _Append = _Concat; - - export type Append = L extends unknown ? A extends unknown ? _Append : never : never; - } - declare module "List/Reverse" { - import { Prepend } from "List/Prepend"; - import { Pos } from "Iteration/Pos"; - import { Next } from "Iteration/Next"; - import { Length } from "List/Length"; - import { IterationOf } from "Iteration/IterationOf"; - import { Iteration } from "Iteration/Iteration"; - import { Cast } from "Any/Cast"; - import { List } from "List/List"; - import { Naked } from "List/_Internal"; - import { Extends } from "Any/Extends"; - - type __Reverse> = { - 0: __Reverse]>, Next>; - 1: LO; - }[Extends, Length>]; - - export type _Reverse = __Reverse, LO> extends infer X ? Cast : never; - ~~~~~~~~ -!!! error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' does not satisfy the constraint 'List'. -!!! error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' is missing the following properties from type 'readonly any[]': length, concat, join, slice, and 9 more. - - export type Reverse = L extends unknown ? LO extends unknown ? _Reverse : never : never; - } - declare module "List/Concat" { - import { _Reverse } from "List/Reverse"; - import { List } from "List/List"; - - export type _Concat = _Reverse<_Reverse, L1>; - - export type Concat = L extends unknown ? L1 extends L1 ? _Concat : never : never; - } - declare module "List/Drop" { - import { Tail } from "List/Tail"; - import { Cast } from "Any/Cast"; - import { IterationOf } from "Iteration/IterationOf"; - import { Iteration } from "Iteration/Iteration"; - import { Number } from "Number/Number"; - import { Way } from "Iteration/_Internal"; - import { List } from "List/List"; - import { Pos } from "Iteration/Pos"; - import { Prev } from "Iteration/Prev"; - import { Prepend } from "List/Prepend"; - import { Naked } from "List/_Internal"; - import { Extends } from "Any/Extends"; - - type DropForth = { - 0: DropForth, Prev>; - 1: L; - }[Extends<0, Pos>]; - - type DropBack, LN extends List = []> = { - 0: DropBack, Prepend]>>; - 1: LN; - }[Extends<-1, Pos>]; - - type __Drop = { - '->': DropForth; - '<-': DropBack; - }[way]; - - export type _Drop = __Drop, IterationOf, way> extends infer X ? Cast : never; - ~~~~~~~~ -!!! error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' does not satisfy the constraint 'List'. -!!! error TS2344: Type '{ [K in keyof Required]: K extends keyof L ? L[K] : Required[K]; }' is missing the following properties from type 'readonly any[]': length, concat, join, slice, and 9 more. - - export type Drop = L extends unknown ? N extends unknown ? _Drop : never : never; - } - declare module "List/Length" { - import { NumberOf } from "Number/NumberOf"; - import { Formats } from "Iteration/_Internal"; - import { List } from "List/List"; - - export type Length = { - 's': NumberOf; - 'n': L['length']; - }[fmt]; - } - declare module "Iteration/Next" { - import { IterationMap } from "Iteration/IterationOf"; - import { Iteration } from "Iteration/Iteration"; - - export type Next = IterationMap[I[1]]; - } - declare module "Any/Cast" { - export type Cast = A1 extends A2 ? A1 : A2; - } - declare module "Function/Parameters" { - import { Function } from "Function/Function"; - - export type Parameters = F extends ((...args: infer L) => any) ? L : never; - } - declare module "Function/Return" { - import { Function } from "Function/Function"; - - export type Return = F extends ((...args: any[]) => infer R) ? R : never; - } - declare module "Iteration/Prev" { - import { IterationMap } from "Iteration/IterationOf"; - import { Iteration } from "Iteration/Iteration"; - - export type Prev = IterationMap[I[0]]; - } - declare module "Number/NumberOf" { - import { IterationMap } from "Iteration/IterationOf"; - import { Key } from "Iteration/Key"; - import { Pos } from "Iteration/Pos"; - import { Numbers } from "Number/_Internal"; - - export type _NumberOf = { - [K in keyof IterationMap]: Pos extends N ? Key : never; - }[keyof IterationMap]; - - export type NumberOf = N extends Numbers['number']['all'] ? _NumberOf : string; - } - declare module "Object/_Internal" { - export type Modx = ['?' | '!', 'W' | 'R']; - - export type Depth = 'flat' | 'deep'; - - export type Empty = { - [K in keyof O]: undefined; - }; - } - declare module "Iteration/IterationOf" { - import { Number } from "Number/Number"; - - export type IterationMap = { - '-40': ['__', '-39', '-40', -40, '-']; - '-39': ['-40', '-38', '-39', -39, '-']; - '-38': ['-39', '-37', '-38', -38, '-']; - '-37': ['-38', '-36', '-37', -37, '-']; - '-36': ['-37', '-35', '-36', -36, '-']; - '-35': ['-36', '-34', '-35', -35, '-']; - '-34': ['-35', '-33', '-34', -34, '-']; - '-33': ['-34', '-32', '-33', -33, '-']; - '-32': ['-33', '-31', '-32', -32, '-']; - '-31': ['-32', '-30', '-31', -31, '-']; - '-30': ['-31', '-29', '-30', -30, '-']; - '-29': ['-30', '-28', '-29', -29, '-']; - '-28': ['-29', '-27', '-28', -28, '-']; - '-27': ['-28', '-26', '-27', -27, '-']; - '-26': ['-27', '-25', '-26', -26, '-']; - '-25': ['-26', '-24', '-25', -25, '-']; - '-24': ['-25', '-23', '-24', -24, '-']; - '-23': ['-24', '-22', '-23', -23, '-']; - '-22': ['-23', '-21', '-22', -22, '-']; - '-21': ['-22', '-20', '-21', -21, '-']; - '-20': ['-21', '-19', '-20', -20, '-']; - '-19': ['-20', '-18', '-19', -19, '-']; - '-18': ['-19', '-17', '-18', -18, '-']; - '-17': ['-18', '-16', '-17', -17, '-']; - '-16': ['-17', '-15', '-16', -16, '-']; - '-15': ['-16', '-14', '-15', -15, '-']; - '-14': ['-15', '-13', '-14', -14, '-']; - '-13': ['-14', '-12', '-13', -13, '-']; - '-12': ['-13', '-11', '-12', -12, '-']; - '-11': ['-12', '-10', '-11', -11, '-']; - '-10': ['-11', '-9', '-10', -10, '-']; - '-9': ['-10', '-8', '-9', -9, '-']; - '-8': ['-9', '-7', '-8', -8, '-']; - '-7': ['-8', '-6', '-7', -7, '-']; - '-6': ['-7', '-5', '-6', -6, '-']; - '-5': ['-6', '-4', '-5', -5, '-']; - '-4': ['-5', '-3', '-4', -4, '-']; - '-3': ['-4', '-2', '-3', -3, '-']; - '-2': ['-3', '-1', '-2', -2, '-']; - '-1': ['-2', '0', '-1', -1, '-']; - '0': ['-1', '1', '0', 0, '0']; - '1': ['0', '2', '1', 1, '+']; - '2': ['1', '3', '2', 2, '+']; - '3': ['2', '4', '3', 3, '+']; - '4': ['3', '5', '4', 4, '+']; - '5': ['4', '6', '5', 5, '+']; - '6': ['5', '7', '6', 6, '+']; - '7': ['6', '8', '7', 7, '+']; - '8': ['7', '9', '8', 8, '+']; - '9': ['8', '10', '9', 9, '+']; - '10': ['9', '11', '10', 10, '+']; - '11': ['10', '12', '11', 11, '+']; - '12': ['11', '13', '12', 12, '+']; - '13': ['12', '14', '13', 13, '+']; - '14': ['13', '15', '14', 14, '+']; - '15': ['14', '16', '15', 15, '+']; - '16': ['15', '17', '16', 16, '+']; - '17': ['16', '18', '17', 17, '+']; - '18': ['17', '19', '18', 18, '+']; - '19': ['18', '20', '19', 19, '+']; - '20': ['19', '21', '20', 20, '+']; - '21': ['20', '22', '21', 21, '+']; - '22': ['21', '23', '22', 22, '+']; - '23': ['22', '24', '23', 23, '+']; - '24': ['23', '25', '24', 24, '+']; - '25': ['24', '26', '25', 25, '+']; - '26': ['25', '27', '26', 26, '+']; - '27': ['26', '28', '27', 27, '+']; - '28': ['27', '29', '28', 28, '+']; - '29': ['28', '30', '29', 29, '+']; - '30': ['29', '31', '30', 30, '+']; - '31': ['30', '32', '31', 31, '+']; - '32': ['31', '33', '32', 32, '+']; - '33': ['32', '34', '33', 33, '+']; - '34': ['33', '35', '34', 34, '+']; - '35': ['34', '36', '35', 35, '+']; - '36': ['35', '37', '36', 36, '+']; - '37': ['36', '38', '37', 37, '+']; - '38': ['37', '39', '38', 38, '+']; - '39': ['38', '40', '39', 39, '+']; - '40': ['39', '__', '40', 40, '+']; - '__': ['__', '__', string, number, '-' | '0' | '+']; - }; - - export type IterationOf = N extends keyof IterationMap ? IterationMap[N] : IterationMap['__']; - } - declare module "Iteration/Iteration" { - import { IterationMap } from "Iteration/IterationOf"; - - export type Iteration = [keyof IterationMap, keyof IterationMap, string, number, '-' | '0' | '+']; - } - declare module "Iteration/Key" { - import { Iteration } from "Iteration/Iteration"; - import { Format } from "Iteration/Format"; - - export type Key = Format; - } - declare module "List/NonNullable" { - import { Depth } from "Object/_Internal"; - import { NonNullable as ONonNullable } from "Object/NonNullable"; - import { ListOf } from "Object/ListOf"; - import { Cast } from "Any/Cast"; - import { Key } from "Any/Key"; - import { ObjectOf } from "List/ObjectOf"; - import { Implements } from "Any/Implements"; - import { Keys } from "List/Keys"; - import { List } from "List/List"; - import { NumberOf } from "Any/_Internal"; - - export type NonNullable = { - 1: Cast, List>; - 0: ListOf, NumberOf, depth>>; - }[Implements, K>] & {}; - } - declare module "Any/Type" { - const symbol: unique symbol; - - export type Type = A & { - [K in typeof symbol]: Id; - }; - } - declare module "Any/x" { - import { Type } from "Any/Type"; - - export type x = Type<{}, 'x'>; - } - declare module "List/List" { - - export type List = ReadonlyArray; - } - declare module "Function/Function" { - import { List } from "List/List"; - - export interface Function

{ - (...args: P): R; - } - } - declare module "Any/Extends" { - export type Extends = [A1] extends [never] ? 0 : A1 extends A2 ? 1 : 0; - } - - declare module "Function/Curry" { - import { Pos } from "Iteration/Pos"; - import { _Append } from "List/Append"; - import { _Concat } from "List/Concat"; - import { _Drop } from "List/Drop"; - import { Length } from "List/Length"; - import { Next } from "Iteration/Next"; - import { Cast } from "Any/Cast"; - import { Parameters } from "Function/Parameters"; - import { Return } from "Function/Return"; - import { IterationOf } from "Iteration/IterationOf"; - import { Iteration } from "Iteration/Iteration"; - import { Key } from "Iteration/Key"; - import { NonNullable } from "List/NonNullable"; - import { x } from "Any/x"; - import { List } from "List/List"; - import { Function } from "Function/Function"; - import { Extends } from "Any/Extends"; - - type GapOf> = L1[Pos] extends x ? _Append]> : LN; - - type _GapsOf> = { - 0: _GapsOf, Next>; - 1: _Concat>>; - }[Extends, Length>]; - - type GapsOf = _GapsOf extends infer X ? Cast : never; - - type Gaps = NonNullable<{ - [K in keyof L]?: L[K] | x; - }>; - - export type Curry = (...args: Cast>>) => GapsOf> extends infer G ? Length> extends infer L ? L extends 0 ? Return : L extends 1 ? Curry<(...args: Cast) => Return> & ((...args: Cast) => Return) : Curry<(...args: Cast) => Return> : never : never; - } - - - \ No newline at end of file From 4b50e120f247ee9b7acdb5e3ca61cf2879a9399e Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 29 Feb 2024 11:43:16 -0800 Subject: [PATCH 12/18] Run format --- src/compiler/checker.ts | 42 ++++++++++++++++++++------------------- src/compiler/utilities.ts | 4 ++-- 2 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a324e3c2f2e49..e11d3c64960f8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1378,20 +1378,19 @@ export interface SpeculationHost { /** * Marks an auto accessor as a cache whose value can be rewound by the checker speculation helper. - * + * * This is implemented by keeping a record of the speculative "epoch" writes are performed at, and * returning the result for the highest epoch that hasn't (yet) been marked as "discarded". * Values stored in discarded epochs are lazily discarded when a read is later performed. - * + * * This is designed to be compatible with both `experimentalDecorators` and the final decorators spec, * so it can be used both in downlevel targets and natively. */ const SpeculatableCache = ( valueOrTarget: ClassAccessorDecoratorTarget | any, _contextOrPropertyKey: ClassAccessorDecoratorContext | string, - descriptor?: PropertyDescriptor + descriptor?: PropertyDescriptor, ): /*ClassAccessorDecoratorResult | void*/ any => { - const baseGet = (descriptor ? descriptor.get! : (valueOrTarget as ClassAccessorDecoratorTarget).get) as (this: T) => V; const baseSet = (descriptor ? descriptor.set! : (valueOrTarget as ClassAccessorDecoratorTarget).set) as (this: T, v: V) => V; @@ -1407,17 +1406,17 @@ const SpeculatableCache = ( values[epoch] = v; return { values, - writtenEpochs + writtenEpochs, }; - } + }, }; function readValue(this: T) { const internals = baseGet.call(this); - if (!internals) { return undefined! } + if (!internals) return undefined!; const { values, - writtenEpochs + writtenEpochs, } = internals; const discardedSpeculativeEpochs = this.host.getDiscardedSpeculativeEpochs(); @@ -1456,14 +1455,14 @@ const SpeculatableCache = ( } const { values, - writtenEpochs + writtenEpochs, } = internals; writtenEpochs.push(currentSpeculativeEpoch); // Store the new value at the desired speculative depth values[currentSpeculativeEpoch] = value!; return value!; } -} +}; /** @internal */ export const enum EnumKind { @@ -1471,7 +1470,6 @@ export const enum EnumKind { Literal, // Literal enum (each member has a TypeFlags.EnumLiteral type) } - /** @internal */ export class SpeculatableLinks { constructor(public host: SpeculationHost) {} @@ -1733,7 +1731,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var speculativeCaches: (any[] | Map | Set | DiagnosticCollection)[] = []; /** * The id of the current speculative execution environment - used by speculation helpers to avoid eagerly doing work. - * + * * This is monotonically increasing, and basically represents a slice of execution time within the checker that we want to * be able to uniquely refer to. */ @@ -1742,9 +1740,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { var discardedSpeculativeEpochs = new Set(); // The speculation host object used by symbol and node links to associate their speculation state with this checker's speculation state var speculationHost: SpeculationHost = { - getCurrentSpeculativeEpoch() { return currentSpeculativeEpoch; }, - getDiscardedSpeculativeEpochs() { return discardedSpeculativeEpochs; }, - } + getCurrentSpeculativeEpoch() { + return currentSpeculativeEpoch; + }, + getDiscardedSpeculativeEpochs() { + return discardedSpeculativeEpochs; + }, + }; var deferredDiagnosticsCallbacks: (() => void)[] = registerSpeculativeCache([]); @@ -44261,7 +44263,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isGeneratorMethod || isIteratorMethod) { const globalType = isGeneratorMethod ? globalGeneratorType : globalIteratorType; const { mapper } = methodType as AnonymousType; - const [ yieldType, returnType, nextType ] = globalType.typeParameters!; + const [yieldType, returnType, nextType] = globalType.typeParameters!; return createIterationTypes( mapper ? getMappedType(yieldType, mapper) : yieldType, mapper ? getMappedType(returnType, mapper) : returnType, @@ -49131,7 +49133,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // TODO: Override error reporting functions to just defer work until speculation // helper is confirmed as locked-in, to avoid the work of building diagnostics until // we know we're actually going to use them. - + function save(cache: (typeof speculativeCaches)[number]): () => void { if (Array.isArray(cache)) { return saveArray(cache); @@ -49160,9 +49162,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function saveMap(cache: Map) { - const original = arrayFrom(cache.entries()) + const original = arrayFrom(cache.entries()); return () => { - cache.clear() + cache.clear(); for (const [k, v] of original) { cache.set(k, v); } @@ -49183,7 +49185,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { const c = cache.checkpoint(); return () => { cache.revert(c); - } + }; } } diff --git a/src/compiler/utilities.ts b/src/compiler/utilities.ts index 1e0a01f86b015..75b4e4321b7c4 100644 --- a/src/compiler/utilities.ts +++ b/src/compiler/utilities.ts @@ -5782,7 +5782,7 @@ export function createDiagnosticCollection(): DiagnosticCollection { getGlobalDiagnostics, getDiagnostics, checkpoint, - revert + revert, }; // TODO: Copying the state at time of checkpoint is slow to checkpoint and memory intensive (but fast to restore) @@ -5792,7 +5792,7 @@ export function createDiagnosticCollection(): DiagnosticCollection { nonFileDiagnostics: nonFileDiagnostics.slice() as SortedArray, filesWithDiagnostics: filesWithDiagnostics.slice() as SortedArray, fileDiagnostics: new Map(map(arrayFrom(fileDiagnostics.entries()), ([k, v]) => [k, v.slice() as SortedArray] as const)), - hasReadNonFileDiagnostics + hasReadNonFileDiagnostics, }; return c as DiagnosticCollectionCheckpoint; } From 1beceeb878f0786b4b65524a460efadccedace5f Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 29 Feb 2024 12:00:27 -0800 Subject: [PATCH 13/18] Backout unrelated change --- src/compiler/checker.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index e11d3c64960f8..73b623bd18eae 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -44263,11 +44263,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { if (isGeneratorMethod || isIteratorMethod) { const globalType = isGeneratorMethod ? globalGeneratorType : globalIteratorType; const { mapper } = methodType as AnonymousType; - const [yieldType, returnType, nextType] = globalType.typeParameters!; return createIterationTypes( - mapper ? getMappedType(yieldType, mapper) : yieldType, - mapper ? getMappedType(returnType, mapper) : returnType, - methodName === "next" ? mapper ? getMappedType(nextType, mapper) : nextType : undefined, + getMappedType(globalType.typeParameters![0], mapper!), + getMappedType(globalType.typeParameters![1], mapper!), + methodName === "next" ? getMappedType(globalType.typeParameters![2], mapper!) : undefined, ); } } From 8605b12eb607a972e1232906d3a22e607f85fcb0 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Thu, 29 Feb 2024 12:01:59 -0800 Subject: [PATCH 14/18] Backout no longer needed lib/target change --- src/tsconfig-base.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tsconfig-base.json b/src/tsconfig-base.json index cdfe4003699c8..7ac1f2ee391a6 100644 --- a/src/tsconfig-base.json +++ b/src/tsconfig-base.json @@ -4,8 +4,8 @@ "outDir": "../built/local", "pretty": true, - "lib": ["es2021"], - "target": "es2021", + "lib": ["es2020"], + "target": "es2020", "module": "NodeNext", "moduleResolution": "NodeNext", "experimentalDecorators": true, From ada8221ad4c17a56b91f952515ad92b15b4cf32c Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 4 Mar 2024 10:54:28 -0800 Subject: [PATCH 15/18] Fix one class of the self-build errors --- src/compiler/checker.ts | 7 +-- .../functionIndirectSelfCallInferedReturn.js | 22 ++++++++ ...ctionIndirectSelfCallInferedReturn.symbols | 51 +++++++++++++++++++ ...unctionIndirectSelfCallInferedReturn.types | 44 ++++++++++++++++ .../functionIndirectSelfCallInferedReturn.ts | 14 +++++ 5 files changed, 135 insertions(+), 3 deletions(-) create mode 100644 tests/baselines/reference/functionIndirectSelfCallInferedReturn.js create mode 100644 tests/baselines/reference/functionIndirectSelfCallInferedReturn.symbols create mode 100644 tests/baselines/reference/functionIndirectSelfCallInferedReturn.types create mode 100644 tests/cases/compiler/functionIndirectSelfCallInferedReturn.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 73b623bd18eae..adbf5f96f66c5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -35165,7 +35165,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return undefined; } let diags: readonly Diagnostic[] | undefined; - if (diags = getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ true, /*containingMessageChain*/ undefined)) { + if (diags = getSignatureApplicabilityError(node, args, candidate, relation, CheckMode.Normal, /*reportErrors*/ relation === assignableRelation, /*containingMessageChain*/ undefined)) { candidatesForArgumentError = [candidate]; candidateArgumentErrors = [diags]; return undefined; @@ -35208,7 +35208,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { checkCandidate = candidate; } let diags: readonly Diagnostic[] | undefined; - if (diags = getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ true, /*containingMessageChain*/ undefined)) { + if (diags = getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ relation === assignableRelation, /*containingMessageChain*/ undefined)) { // Give preference to error candidates that have no rest parameters (as they are more specific) (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); (candidateArgumentErrors ||= []).push(diags); @@ -35229,7 +35229,8 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return false; } } - if (diags = getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ true, /*containingMessageChain*/ undefined)) { + + if (diags = getSignatureApplicabilityError(node, args, checkCandidate, relation, argCheckMode, /*reportErrors*/ relation === assignableRelation, /*containingMessageChain*/ undefined)) { // Give preference to error candidates that have no rest parameters (as they are more specific) (candidatesForArgumentError || (candidatesForArgumentError = [])).push(checkCandidate); (candidateArgumentErrors ||= []).push(diags); diff --git a/tests/baselines/reference/functionIndirectSelfCallInferedReturn.js b/tests/baselines/reference/functionIndirectSelfCallInferedReturn.js new file mode 100644 index 0000000000000..d99df6efc83d5 --- /dev/null +++ b/tests/baselines/reference/functionIndirectSelfCallInferedReturn.js @@ -0,0 +1,22 @@ +//// [tests/cases/compiler/functionIndirectSelfCallInferedReturn.ts] //// + +//// [functionIndirectSelfCallInferedReturn.ts] +interface Type { + flags: number; + x: any; +} + +declare function mapType(type: Type, mapper: (t: Type) => Type, noReductions?: boolean): Type; +declare function mapType(type: Type, mapper: (t: Type) => Type | undefined, noReductions?: boolean): Type | undefined; + +function unwrapAwaitedType(type: Type) { + return type.flags & 1 ? mapType(type, unwrapAwaitedType) : + type; +} + +//// [functionIndirectSelfCallInferedReturn.js] +"use strict"; +function unwrapAwaitedType(type) { + return type.flags & 1 ? mapType(type, unwrapAwaitedType) : + type; +} diff --git a/tests/baselines/reference/functionIndirectSelfCallInferedReturn.symbols b/tests/baselines/reference/functionIndirectSelfCallInferedReturn.symbols new file mode 100644 index 0000000000000..227c13efd5ea7 --- /dev/null +++ b/tests/baselines/reference/functionIndirectSelfCallInferedReturn.symbols @@ -0,0 +1,51 @@ +//// [tests/cases/compiler/functionIndirectSelfCallInferedReturn.ts] //// + +=== functionIndirectSelfCallInferedReturn.ts === +interface Type { +>Type : Symbol(Type, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 0)) + + flags: number; +>flags : Symbol(Type.flags, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 16)) + + x: any; +>x : Symbol(Type.x, Decl(functionIndirectSelfCallInferedReturn.ts, 1, 18)) +} + +declare function mapType(type: Type, mapper: (t: Type) => Type, noReductions?: boolean): Type; +>mapType : Symbol(mapType, Decl(functionIndirectSelfCallInferedReturn.ts, 3, 1), Decl(functionIndirectSelfCallInferedReturn.ts, 5, 94)) +>type : Symbol(type, Decl(functionIndirectSelfCallInferedReturn.ts, 5, 25)) +>Type : Symbol(Type, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 0)) +>mapper : Symbol(mapper, Decl(functionIndirectSelfCallInferedReturn.ts, 5, 36)) +>t : Symbol(t, Decl(functionIndirectSelfCallInferedReturn.ts, 5, 46)) +>Type : Symbol(Type, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 0)) +>Type : Symbol(Type, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 0)) +>noReductions : Symbol(noReductions, Decl(functionIndirectSelfCallInferedReturn.ts, 5, 63)) +>Type : Symbol(Type, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 0)) + +declare function mapType(type: Type, mapper: (t: Type) => Type | undefined, noReductions?: boolean): Type | undefined; +>mapType : Symbol(mapType, Decl(functionIndirectSelfCallInferedReturn.ts, 3, 1), Decl(functionIndirectSelfCallInferedReturn.ts, 5, 94)) +>type : Symbol(type, Decl(functionIndirectSelfCallInferedReturn.ts, 6, 25)) +>Type : Symbol(Type, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 0)) +>mapper : Symbol(mapper, Decl(functionIndirectSelfCallInferedReturn.ts, 6, 36)) +>t : Symbol(t, Decl(functionIndirectSelfCallInferedReturn.ts, 6, 46)) +>Type : Symbol(Type, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 0)) +>Type : Symbol(Type, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 0)) +>noReductions : Symbol(noReductions, Decl(functionIndirectSelfCallInferedReturn.ts, 6, 75)) +>Type : Symbol(Type, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 0)) + +function unwrapAwaitedType(type: Type) { +>unwrapAwaitedType : Symbol(unwrapAwaitedType, Decl(functionIndirectSelfCallInferedReturn.ts, 6, 118)) +>type : Symbol(type, Decl(functionIndirectSelfCallInferedReturn.ts, 8, 27)) +>Type : Symbol(Type, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 0)) + + return type.flags & 1 ? mapType(type, unwrapAwaitedType) : +>type.flags : Symbol(Type.flags, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 16)) +>type : Symbol(type, Decl(functionIndirectSelfCallInferedReturn.ts, 8, 27)) +>flags : Symbol(Type.flags, Decl(functionIndirectSelfCallInferedReturn.ts, 0, 16)) +>mapType : Symbol(mapType, Decl(functionIndirectSelfCallInferedReturn.ts, 3, 1), Decl(functionIndirectSelfCallInferedReturn.ts, 5, 94)) +>type : Symbol(type, Decl(functionIndirectSelfCallInferedReturn.ts, 8, 27)) +>unwrapAwaitedType : Symbol(unwrapAwaitedType, Decl(functionIndirectSelfCallInferedReturn.ts, 6, 118)) + + type; +>type : Symbol(type, Decl(functionIndirectSelfCallInferedReturn.ts, 8, 27)) +} diff --git a/tests/baselines/reference/functionIndirectSelfCallInferedReturn.types b/tests/baselines/reference/functionIndirectSelfCallInferedReturn.types new file mode 100644 index 0000000000000..6c9b86e427ed6 --- /dev/null +++ b/tests/baselines/reference/functionIndirectSelfCallInferedReturn.types @@ -0,0 +1,44 @@ +//// [tests/cases/compiler/functionIndirectSelfCallInferedReturn.ts] //// + +=== functionIndirectSelfCallInferedReturn.ts === +interface Type { + flags: number; +>flags : number + + x: any; +>x : any +} + +declare function mapType(type: Type, mapper: (t: Type) => Type, noReductions?: boolean): Type; +>mapType : { (type: Type, mapper: (t: Type) => Type, noReductions?: boolean): Type; (type: Type, mapper: (t: Type) => Type | undefined, noReductions?: boolean | undefined): Type | undefined; } +>type : Type +>mapper : (t: Type) => Type +>t : Type +>noReductions : boolean | undefined + +declare function mapType(type: Type, mapper: (t: Type) => Type | undefined, noReductions?: boolean): Type | undefined; +>mapType : { (type: Type, mapper: (t: Type) => Type, noReductions?: boolean | undefined): Type; (type: Type, mapper: (t: Type) => Type | undefined, noReductions?: boolean): Type | undefined; } +>type : Type +>mapper : (t: Type) => Type | undefined +>t : Type +>noReductions : boolean | undefined + +function unwrapAwaitedType(type: Type) { +>unwrapAwaitedType : (type: Type) => Type +>type : Type + + return type.flags & 1 ? mapType(type, unwrapAwaitedType) : +>type.flags & 1 ? mapType(type, unwrapAwaitedType) : type : Type +>type.flags & 1 : number +>type.flags : number +>type : Type +>flags : number +>1 : 1 +>mapType(type, unwrapAwaitedType) : Type +>mapType : { (type: Type, mapper: (t: Type) => Type, noReductions?: boolean | undefined): Type; (type: Type, mapper: (t: Type) => Type | undefined, noReductions?: boolean | undefined): Type | undefined; } +>type : Type +>unwrapAwaitedType : (type: Type) => Type + + type; +>type : Type +} diff --git a/tests/cases/compiler/functionIndirectSelfCallInferedReturn.ts b/tests/cases/compiler/functionIndirectSelfCallInferedReturn.ts new file mode 100644 index 0000000000000..bb5bf61ef2d0b --- /dev/null +++ b/tests/cases/compiler/functionIndirectSelfCallInferedReturn.ts @@ -0,0 +1,14 @@ +// @strict: true + +interface Type { + flags: number; + x: any; +} + +declare function mapType(type: Type, mapper: (t: Type) => Type, noReductions?: boolean): Type; +declare function mapType(type: Type, mapper: (t: Type) => Type | undefined, noReductions?: boolean): Type | undefined; + +function unwrapAwaitedType(type: Type) { + return type.flags & 1 ? mapType(type, unwrapAwaitedType) : + type; +} \ No newline at end of file From e92f50bfd4c51b5d832b64e7797b1c9b700983b7 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 4 Mar 2024 13:32:44 -0800 Subject: [PATCH 16/18] Now that we speculate, we can and should reset argCheckMode for every overload we check --- src/compiler/checker.ts | 3 +- ...StringLiteralsInJsxAttributes02.errors.txt | 7 +- .../reference/destructuringTuple.errors.txt | 26 ++++- .../reference/destructuringTuple.types | 8 +- ...unctionOverloadInformsPriorArgumentType.js | 38 +++++++ ...onOverloadInformsPriorArgumentType.symbols | 97 ++++++++++++++++ ...tionOverloadInformsPriorArgumentType.types | 89 +++++++++++++++ ...torFixesInferencesAppropriately.errors.txt | 34 ------ ...ructorFixesInferencesAppropriately.symbols | 2 + ...structorFixesInferencesAppropriately.types | 16 +-- .../overloadsWithProvisionalErrors.errors.txt | 8 +- .../parenthesizedContexualTyping1.types | 106 +++++++++--------- ...elessFunctionComponentOverload5.errors.txt | 7 +- ...unctionOverloadInformsPriorArgumentType.ts | 23 ++++ 14 files changed, 346 insertions(+), 118 deletions(-) create mode 100644 tests/baselines/reference/functionOverloadInformsPriorArgumentType.js create mode 100644 tests/baselines/reference/functionOverloadInformsPriorArgumentType.symbols create mode 100644 tests/baselines/reference/functionOverloadInformsPriorArgumentType.types delete mode 100644 tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.errors.txt create mode 100644 tests/cases/compiler/functionOverloadInformsPriorArgumentType.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index adbf5f96f66c5..b0ff4e43ec52f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -34964,7 +34964,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // For a decorator, no arguments are susceptible to contextual typing due to the fact // decorators are applied to a declaration by the emitter, and not to an expression. const isSingleNonGenericCandidate = candidates.length === 1 && !candidates[0].typeParameters; - let argCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal; // The following variables are captured and modified by calls to chooseOverload. // If overload resolution or type argument inference fails, we want to report the @@ -35173,12 +35172,14 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { return candidate; } + const initialCheckMode = !isDecorator && !isSingleNonGenericCandidate && some(args, isContextSensitive) ? CheckMode.SkipContextSensitive : CheckMode.Normal; for (let candidateIndex = 0; candidateIndex < candidates.length; candidateIndex++) { const candidate = candidates[candidateIndex]; if (!hasCorrectTypeArgumentArity(candidate, typeArguments) || !hasCorrectArity(node, args, candidate, signatureHelpTrailingComma)) { continue; } const result = speculate(() => { + let argCheckMode = initialCheckMode; let checkCandidate: Signature; let inferenceContext: InferenceContext | undefined; diff --git a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt index e6be2d50b6119..a35f3bdf47608 100644 --- a/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt +++ b/tests/baselines/reference/contextuallyTypedStringLiteralsInJsxAttributes02.errors.txt @@ -10,8 +10,7 @@ file.tsx(28,13): error TS2769: No overload matches this call. Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. Overload 2 of 2, '(linkProps: LinkProps): Element', gave the following error. - Type '{ onClick: (k: any) => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. - Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. + Property 'goTo' is missing in type '{ onClick: {}; extra: true; }' but required in type 'LinkProps'. file.tsx(29,43): error TS2769: No overload matches this call. Overload 1 of 2, '(buttonProps: ButtonProps): Element', gave the following error. Type '{ extra: true; goTo: string; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. @@ -75,8 +74,8 @@ file.tsx(36,44): error TS2322: Type '{ extra: true; goTo: "home"; }' is not assi !!! error TS2769: Type '{ onClick: (k: "left" | "right") => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & ButtonProps'. !!! error TS2769: Property 'extra' does not exist on type 'IntrinsicAttributes & ButtonProps'. !!! error TS2769: Overload 2 of 2, '(linkProps: LinkProps): Element', gave the following error. -!!! error TS2769: Type '{ onClick: (k: any) => void; extra: true; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. -!!! error TS2769: Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. +!!! error TS2769: Property 'goTo' is missing in type '{ onClick: {}; extra: true; }' but required in type 'LinkProps'. +!!! related TS2728 file.tsx:13:5: 'goTo' is declared here. const b3 = ; // goTo has type"home" | "contact" ~~~~~ !!! error TS2769: No overload matches this call. diff --git a/tests/baselines/reference/destructuringTuple.errors.txt b/tests/baselines/reference/destructuringTuple.errors.txt index 37458392b906d..0650c5e002195 100644 --- a/tests/baselines/reference/destructuringTuple.errors.txt +++ b/tests/baselines/reference/destructuringTuple.errors.txt @@ -1,8 +1,14 @@ -destructuringTuple.ts(11,7): error TS2461: Type 'unknown' is not an array type. -destructuringTuple.ts(11,48): error TS18046: 'accu' is of type 'unknown'. +destructuringTuple.ts(11,7): error TS2461: Type 'number' is not an array type. +destructuringTuple.ts(11,27): error TS2769: No overload matches this call. + Overload 1 of 3, '(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number', gave the following error. + Argument of type 'never[]' is not assignable to parameter of type 'number'. + Overload 2 of 3, '(callbackfn: (previousValue: [], currentValue: number, currentIndex: number, array: number[]) => [], initialValue: []): []', gave the following error. + Type 'never[]' is not assignable to type '[]'. + Target allows only 0 element(s) but source may have more. +destructuringTuple.ts(11,53): error TS2339: Property 'concat' does not exist on type 'number'. -==== destructuringTuple.ts (2 errors) ==== +==== destructuringTuple.ts (3 errors) ==== declare var tuple: [boolean, number, ...string[]]; const [a, b, c, ...rest] = tuple; @@ -15,9 +21,17 @@ destructuringTuple.ts(11,48): error TS18046: 'accu' is of type 'unknown'. const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); ~~~~~~~ -!!! error TS2461: Type 'unknown' is not an array type. - ~~~~ -!!! error TS18046: 'accu' is of type 'unknown'. +!!! error TS2461: Type 'number' is not an array type. + ~~~~~~ +!!! error TS2769: No overload matches this call. +!!! error TS2769: Overload 1 of 3, '(callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number', gave the following error. +!!! error TS2769: Argument of type 'never[]' is not assignable to parameter of type 'number'. +!!! error TS2769: Overload 2 of 3, '(callbackfn: (previousValue: [], currentValue: number, currentIndex: number, array: number[]) => [], initialValue: []): []', gave the following error. +!!! error TS2769: Type 'never[]' is not assignable to type '[]'. +!!! error TS2769: Target allows only 0 element(s) but source may have more. +!!! related TS6502 lib.es5.d.ts:--:--: The expected type comes from the return type of this signature. + ~~~~~~ +!!! error TS2339: Property 'concat' does not exist on type 'number'. const [oops2] = [1, 2, 3].reduce((acc: number[], e) => acc.concat(e), []); \ No newline at end of file diff --git a/tests/baselines/reference/destructuringTuple.types b/tests/baselines/reference/destructuringTuple.types index 36538fe41fb4c..a0adc01468cd7 100644 --- a/tests/baselines/reference/destructuringTuple.types +++ b/tests/baselines/reference/destructuringTuple.types @@ -26,19 +26,19 @@ declare var receiver: typeof tuple; const [oops1] = [1, 2, 3].reduce((accu, el) => accu.concat(el), []); >oops1 : any ->[1, 2, 3].reduce((accu, el) => accu.concat(el), []) : unknown +>[1, 2, 3].reduce((accu, el) => accu.concat(el), []) : number >[1, 2, 3].reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } >[1, 2, 3] : number[] >1 : 1 >2 : 2 >3 : 3 >reduce : { (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number): number; (callbackfn: (previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number, initialValue: number): number; (callbackfn: (previousValue: U, currentValue: number, currentIndex: number, array: number[]) => U, initialValue: U): U; } ->(accu, el) => accu.concat(el) : (accu: unknown, el: number) => any ->accu : unknown +>(accu, el) => accu.concat(el) : (accu: number, el: number) => any +>accu : number >el : number >accu.concat(el) : any >accu.concat : any ->accu : unknown +>accu : number >concat : any >el : number >[] : never[] diff --git a/tests/baselines/reference/functionOverloadInformsPriorArgumentType.js b/tests/baselines/reference/functionOverloadInformsPriorArgumentType.js new file mode 100644 index 0000000000000..7f577733a42cf --- /dev/null +++ b/tests/baselines/reference/functionOverloadInformsPriorArgumentType.js @@ -0,0 +1,38 @@ +//// [tests/cases/compiler/functionOverloadInformsPriorArgumentType.ts] //// + +//// [functionOverloadInformsPriorArgumentType.ts] +enum ModifierFlags { + None = 0, + In = 1, + Out = 2, + Const = 4, + Other = 8, +} + +interface Declaration { + modifierFlags: ModifierFlags; +} + +declare function getEffectiveModifierFlags(d: Declaration): ModifierFlags; + +declare function reduceLeft(array: readonly T[] | undefined, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U; +// only has an issue when the 2nd overload is present, even though it has an arity mismatch +declare function reduceLeft(array: readonly T[], f: (memo: T, value: T, i: number) => T): T | undefined; + +function getTypeParameterModifiers(declarations: Declaration[]): ModifierFlags { + return reduceLeft(declarations, (modifiers, d) => modifiers | getEffectiveModifierFlags(d), ModifierFlags.None) & (ModifierFlags.In | ModifierFlags.Out | ModifierFlags.Const); +} + +//// [functionOverloadInformsPriorArgumentType.js] +"use strict"; +var ModifierFlags; +(function (ModifierFlags) { + ModifierFlags[ModifierFlags["None"] = 0] = "None"; + ModifierFlags[ModifierFlags["In"] = 1] = "In"; + ModifierFlags[ModifierFlags["Out"] = 2] = "Out"; + ModifierFlags[ModifierFlags["Const"] = 4] = "Const"; + ModifierFlags[ModifierFlags["Other"] = 8] = "Other"; +})(ModifierFlags || (ModifierFlags = {})); +function getTypeParameterModifiers(declarations) { + return reduceLeft(declarations, function (modifiers, d) { return modifiers | getEffectiveModifierFlags(d); }, ModifierFlags.None) & (ModifierFlags.In | ModifierFlags.Out | ModifierFlags.Const); +} diff --git a/tests/baselines/reference/functionOverloadInformsPriorArgumentType.symbols b/tests/baselines/reference/functionOverloadInformsPriorArgumentType.symbols new file mode 100644 index 0000000000000..149803f4c151a --- /dev/null +++ b/tests/baselines/reference/functionOverloadInformsPriorArgumentType.symbols @@ -0,0 +1,97 @@ +//// [tests/cases/compiler/functionOverloadInformsPriorArgumentType.ts] //// + +=== functionOverloadInformsPriorArgumentType.ts === +enum ModifierFlags { +>ModifierFlags : Symbol(ModifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 0)) + + None = 0, +>None : Symbol(ModifierFlags.None, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 20)) + + In = 1, +>In : Symbol(ModifierFlags.In, Decl(functionOverloadInformsPriorArgumentType.ts, 1, 13)) + + Out = 2, +>Out : Symbol(ModifierFlags.Out, Decl(functionOverloadInformsPriorArgumentType.ts, 2, 11)) + + Const = 4, +>Const : Symbol(ModifierFlags.Const, Decl(functionOverloadInformsPriorArgumentType.ts, 3, 12)) + + Other = 8, +>Other : Symbol(ModifierFlags.Other, Decl(functionOverloadInformsPriorArgumentType.ts, 4, 14)) +} + +interface Declaration { +>Declaration : Symbol(Declaration, Decl(functionOverloadInformsPriorArgumentType.ts, 6, 1)) + + modifierFlags: ModifierFlags; +>modifierFlags : Symbol(Declaration.modifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 8, 23)) +>ModifierFlags : Symbol(ModifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 0)) +} + +declare function getEffectiveModifierFlags(d: Declaration): ModifierFlags; +>getEffectiveModifierFlags : Symbol(getEffectiveModifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 10, 1)) +>d : Symbol(d, Decl(functionOverloadInformsPriorArgumentType.ts, 12, 43)) +>Declaration : Symbol(Declaration, Decl(functionOverloadInformsPriorArgumentType.ts, 6, 1)) +>ModifierFlags : Symbol(ModifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 0)) + +declare function reduceLeft(array: readonly T[] | undefined, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U; +>reduceLeft : Symbol(reduceLeft, Decl(functionOverloadInformsPriorArgumentType.ts, 12, 74), Decl(functionOverloadInformsPriorArgumentType.ts, 14, 154)) +>T : Symbol(T, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 28)) +>U : Symbol(U, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 30)) +>array : Symbol(array, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 34)) +>T : Symbol(T, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 28)) +>f : Symbol(f, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 66)) +>memo : Symbol(memo, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 71)) +>U : Symbol(U, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 30)) +>value : Symbol(value, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 79)) +>T : Symbol(T, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 28)) +>i : Symbol(i, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 89)) +>U : Symbol(U, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 30)) +>initial : Symbol(initial, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 106)) +>U : Symbol(U, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 30)) +>start : Symbol(start, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 118)) +>count : Symbol(count, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 134)) +>U : Symbol(U, Decl(functionOverloadInformsPriorArgumentType.ts, 14, 30)) + +// only has an issue when the 2nd overload is present, even though it has an arity mismatch +declare function reduceLeft(array: readonly T[], f: (memo: T, value: T, i: number) => T): T | undefined; +>reduceLeft : Symbol(reduceLeft, Decl(functionOverloadInformsPriorArgumentType.ts, 12, 74), Decl(functionOverloadInformsPriorArgumentType.ts, 14, 154)) +>T : Symbol(T, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 28)) +>array : Symbol(array, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 31)) +>T : Symbol(T, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 28)) +>f : Symbol(f, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 51)) +>memo : Symbol(memo, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 56)) +>T : Symbol(T, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 28)) +>value : Symbol(value, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 64)) +>T : Symbol(T, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 28)) +>i : Symbol(i, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 74)) +>T : Symbol(T, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 28)) +>T : Symbol(T, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 28)) + +function getTypeParameterModifiers(declarations: Declaration[]): ModifierFlags { +>getTypeParameterModifiers : Symbol(getTypeParameterModifiers, Decl(functionOverloadInformsPriorArgumentType.ts, 16, 107)) +>declarations : Symbol(declarations, Decl(functionOverloadInformsPriorArgumentType.ts, 18, 35)) +>Declaration : Symbol(Declaration, Decl(functionOverloadInformsPriorArgumentType.ts, 6, 1)) +>ModifierFlags : Symbol(ModifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 0)) + + return reduceLeft(declarations, (modifiers, d) => modifiers | getEffectiveModifierFlags(d), ModifierFlags.None) & (ModifierFlags.In | ModifierFlags.Out | ModifierFlags.Const); +>reduceLeft : Symbol(reduceLeft, Decl(functionOverloadInformsPriorArgumentType.ts, 12, 74), Decl(functionOverloadInformsPriorArgumentType.ts, 14, 154)) +>declarations : Symbol(declarations, Decl(functionOverloadInformsPriorArgumentType.ts, 18, 35)) +>modifiers : Symbol(modifiers, Decl(functionOverloadInformsPriorArgumentType.ts, 19, 37)) +>d : Symbol(d, Decl(functionOverloadInformsPriorArgumentType.ts, 19, 47)) +>modifiers : Symbol(modifiers, Decl(functionOverloadInformsPriorArgumentType.ts, 19, 37)) +>getEffectiveModifierFlags : Symbol(getEffectiveModifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 10, 1)) +>d : Symbol(d, Decl(functionOverloadInformsPriorArgumentType.ts, 19, 47)) +>ModifierFlags.None : Symbol(ModifierFlags.None, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 20)) +>ModifierFlags : Symbol(ModifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 0)) +>None : Symbol(ModifierFlags.None, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 20)) +>ModifierFlags.In : Symbol(ModifierFlags.In, Decl(functionOverloadInformsPriorArgumentType.ts, 1, 13)) +>ModifierFlags : Symbol(ModifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 0)) +>In : Symbol(ModifierFlags.In, Decl(functionOverloadInformsPriorArgumentType.ts, 1, 13)) +>ModifierFlags.Out : Symbol(ModifierFlags.Out, Decl(functionOverloadInformsPriorArgumentType.ts, 2, 11)) +>ModifierFlags : Symbol(ModifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 0)) +>Out : Symbol(ModifierFlags.Out, Decl(functionOverloadInformsPriorArgumentType.ts, 2, 11)) +>ModifierFlags.Const : Symbol(ModifierFlags.Const, Decl(functionOverloadInformsPriorArgumentType.ts, 3, 12)) +>ModifierFlags : Symbol(ModifierFlags, Decl(functionOverloadInformsPriorArgumentType.ts, 0, 0)) +>Const : Symbol(ModifierFlags.Const, Decl(functionOverloadInformsPriorArgumentType.ts, 3, 12)) +} diff --git a/tests/baselines/reference/functionOverloadInformsPriorArgumentType.types b/tests/baselines/reference/functionOverloadInformsPriorArgumentType.types new file mode 100644 index 0000000000000..d9039c5b5d308 --- /dev/null +++ b/tests/baselines/reference/functionOverloadInformsPriorArgumentType.types @@ -0,0 +1,89 @@ +//// [tests/cases/compiler/functionOverloadInformsPriorArgumentType.ts] //// + +=== functionOverloadInformsPriorArgumentType.ts === +enum ModifierFlags { +>ModifierFlags : ModifierFlags + + None = 0, +>None : ModifierFlags.None +>0 : 0 + + In = 1, +>In : ModifierFlags.In +>1 : 1 + + Out = 2, +>Out : ModifierFlags.Out +>2 : 2 + + Const = 4, +>Const : ModifierFlags.Const +>4 : 4 + + Other = 8, +>Other : ModifierFlags.Other +>8 : 8 +} + +interface Declaration { + modifierFlags: ModifierFlags; +>modifierFlags : ModifierFlags +} + +declare function getEffectiveModifierFlags(d: Declaration): ModifierFlags; +>getEffectiveModifierFlags : (d: Declaration) => ModifierFlags +>d : Declaration + +declare function reduceLeft(array: readonly T[] | undefined, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U; +>reduceLeft : { (array: readonly T[] | undefined, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U; (array: readonly T_1[], f: (memo: T_1, value: T_1, i: number) => T_1): T_1 | undefined; } +>array : readonly T[] | undefined +>f : (memo: U, value: T, i: number) => U +>memo : U +>value : T +>i : number +>initial : U +>start : number | undefined +>count : number | undefined + +// only has an issue when the 2nd overload is present, even though it has an arity mismatch +declare function reduceLeft(array: readonly T[], f: (memo: T, value: T, i: number) => T): T | undefined; +>reduceLeft : { (array: readonly T_1[] | undefined, f: (memo: U, value: T_1, i: number) => U, initial: U, start?: number | undefined, count?: number | undefined): U; (array: readonly T[], f: (memo: T, value: T, i: number) => T): T | undefined; } +>array : readonly T[] +>f : (memo: T, value: T, i: number) => T +>memo : T +>value : T +>i : number + +function getTypeParameterModifiers(declarations: Declaration[]): ModifierFlags { +>getTypeParameterModifiers : (declarations: Declaration[]) => ModifierFlags +>declarations : Declaration[] + + return reduceLeft(declarations, (modifiers, d) => modifiers | getEffectiveModifierFlags(d), ModifierFlags.None) & (ModifierFlags.In | ModifierFlags.Out | ModifierFlags.Const); +>reduceLeft(declarations, (modifiers, d) => modifiers | getEffectiveModifierFlags(d), ModifierFlags.None) & (ModifierFlags.In | ModifierFlags.Out | ModifierFlags.Const) : number +>reduceLeft(declarations, (modifiers, d) => modifiers | getEffectiveModifierFlags(d), ModifierFlags.None) : ModifierFlags +>reduceLeft : { (array: readonly T[] | undefined, f: (memo: U, value: T, i: number) => U, initial: U, start?: number | undefined, count?: number | undefined): U; (array: readonly T_1[], f: (memo: T_1, value: T_1, i: number) => T_1): T_1 | undefined; } +>declarations : Declaration[] +>(modifiers, d) => modifiers | getEffectiveModifierFlags(d) : (modifiers: ModifierFlags, d: Declaration) => number +>modifiers : ModifierFlags +>d : Declaration +>modifiers | getEffectiveModifierFlags(d) : number +>modifiers : ModifierFlags +>getEffectiveModifierFlags(d) : ModifierFlags +>getEffectiveModifierFlags : (d: Declaration) => ModifierFlags +>d : Declaration +>ModifierFlags.None : ModifierFlags.None +>ModifierFlags : typeof ModifierFlags +>None : ModifierFlags.None +>(ModifierFlags.In | ModifierFlags.Out | ModifierFlags.Const) : number +>ModifierFlags.In | ModifierFlags.Out | ModifierFlags.Const : number +>ModifierFlags.In | ModifierFlags.Out : number +>ModifierFlags.In : ModifierFlags.In +>ModifierFlags : typeof ModifierFlags +>In : ModifierFlags.In +>ModifierFlags.Out : ModifierFlags.Out +>ModifierFlags : typeof ModifierFlags +>Out : ModifierFlags.Out +>ModifierFlags.Const : ModifierFlags.Const +>ModifierFlags : typeof ModifierFlags +>Const : ModifierFlags.Const +} diff --git a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.errors.txt b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.errors.txt deleted file mode 100644 index e0211a09473ba..0000000000000 --- a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.errors.txt +++ /dev/null @@ -1,34 +0,0 @@ -overloadedConstructorFixesInferencesAppropriately.ts(26,32): error TS2339: Property 'success' does not exist on type '{}'. - - -==== overloadedConstructorFixesInferencesAppropriately.ts (1 errors) ==== - interface Box { - v: T; - } - - interface ErrorResult { - readonly error: true - } - - interface AsyncLoaderProps { - readonly asyncLoad: () => Box; - readonly children: (result: Exclude) => string; - } - - class AsyncLoader { - constructor(props: string, context: any); - constructor(props: AsyncLoaderProps); - constructor(...args: any[]) {} - } - - function load(): Box<{ success: true } | ErrorResult> { - return null as any; - } - - new AsyncLoader({ - asyncLoad: load, - children: result => result.success as any, - ~~~~~~~ -!!! error TS2339: Property 'success' does not exist on type '{}'. - }); // should work fine - \ No newline at end of file diff --git a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols index 1448ef2a2bf42..d547c072ef6ca 100644 --- a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols +++ b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.symbols @@ -70,7 +70,9 @@ new AsyncLoader({ children: result => result.success as any, >children : Symbol(children, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 24, 20)) >result : Symbol(result, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 25, 13)) +>result.success : Symbol(success, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 19, 22)) >result : Symbol(result, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 25, 13)) +>success : Symbol(success, Decl(overloadedConstructorFixesInferencesAppropriately.ts, 19, 22)) }); // should work fine diff --git a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types index ad41689f296b4..29ab9ea9b9b9b 100644 --- a/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types +++ b/tests/baselines/reference/overloadedConstructorFixesInferencesAppropriately.types @@ -45,22 +45,22 @@ function load(): Box<{ success: true } | ErrorResult> { } new AsyncLoader({ ->new AsyncLoader({ asyncLoad: load, children: result => result.success as any,}) : AsyncLoader<{}> +>new AsyncLoader({ asyncLoad: load, children: result => result.success as any,}) : AsyncLoader >AsyncLoader : typeof AsyncLoader ->{ asyncLoad: load, children: result => result.success as any,} : { asyncLoad: () => Box; children: (result: {}) => any; } +>{ asyncLoad: load, children: result => result.success as any,} : { asyncLoad: () => Box; children: (result: { success: true; }) => any; } asyncLoad: load, >asyncLoad : () => Box >load : () => Box children: result => result.success as any, ->children : (result: {}) => any ->result => result.success as any : (result: {}) => any ->result : {} +>children : (result: { success: true; }) => any +>result => result.success as any : (result: { success: true; }) => any +>result : { success: true; } >result.success as any : any ->result.success : any ->result : {} ->success : any +>result.success : true +>result : { success: true; } +>success : true }); // should work fine diff --git a/tests/baselines/reference/overloadsWithProvisionalErrors.errors.txt b/tests/baselines/reference/overloadsWithProvisionalErrors.errors.txt index 3e7779b5bb99d..57964a1bcb22a 100644 --- a/tests/baselines/reference/overloadsWithProvisionalErrors.errors.txt +++ b/tests/baselines/reference/overloadsWithProvisionalErrors.errors.txt @@ -1,12 +1,12 @@ overloadsWithProvisionalErrors.ts(6,1): error TS2769: No overload matches this call. Overload 1 of 2, '(s: string): number', gave the following error. - Argument of type '(s: any) => {}' is not assignable to parameter of type 'string'. + Argument of type '{}' is not assignable to parameter of type 'string'. Overload 2 of 2, '(lambda: (s: string) => { a: number; b: number; }): string', gave the following error. Type '{}' is missing the following properties from type '{ a: number; b: number; }': a, b overloadsWithProvisionalErrors.ts(7,17): error TS2304: Cannot find name 'blah'. overloadsWithProvisionalErrors.ts(8,1): error TS2769: No overload matches this call. Overload 1 of 2, '(s: string): number', gave the following error. - Argument of type '(s: any) => { a: any; }' is not assignable to parameter of type 'string'. + Argument of type '{}' is not assignable to parameter of type 'string'. Overload 2 of 2, '(lambda: (s: string) => { a: number; b: number; }): string', gave the following error. Property 'b' is missing in type '{ a: any; }' but required in type '{ a: number; b: number; }'. overloadsWithProvisionalErrors.ts(8,17): error TS2304: Cannot find name 'blah'. @@ -22,7 +22,7 @@ overloadsWithProvisionalErrors.ts(8,17): error TS2304: Cannot find name 'blah'. ~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(s: string): number', gave the following error. -!!! error TS2769: Argument of type '(s: any) => {}' is not assignable to parameter of type 'string'. +!!! error TS2769: Argument of type '{}' is not assignable to parameter of type 'string'. !!! error TS2769: Overload 2 of 2, '(lambda: (s: string) => { a: number; b: number; }): string', gave the following error. !!! error TS2769: Type '{}' is missing the following properties from type '{ a: number; b: number; }': a, b !!! related TS6502 overloadsWithProvisionalErrors.ts:3:14: The expected type comes from the return type of this signature. @@ -33,7 +33,7 @@ overloadsWithProvisionalErrors.ts(8,17): error TS2304: Cannot find name 'blah'. ~~~~ !!! error TS2769: No overload matches this call. !!! error TS2769: Overload 1 of 2, '(s: string): number', gave the following error. -!!! error TS2769: Argument of type '(s: any) => { a: any; }' is not assignable to parameter of type 'string'. +!!! error TS2769: Argument of type '{}' is not assignable to parameter of type 'string'. !!! error TS2769: Overload 2 of 2, '(lambda: (s: string) => { a: number; b: number; }): string', gave the following error. !!! error TS2769: Property 'b' is missing in type '{ a: any; }' but required in type '{ a: number; b: number; }'. !!! related TS2728 overloadsWithProvisionalErrors.ts:3:42: 'b' is declared here. diff --git a/tests/baselines/reference/parenthesizedContexualTyping1.types b/tests/baselines/reference/parenthesizedContexualTyping1.types index 75c3d892c8014..faea74f5755e4 100644 --- a/tests/baselines/reference/parenthesizedContexualTyping1.types +++ b/tests/baselines/reference/parenthesizedContexualTyping1.types @@ -130,100 +130,100 @@ var h = fun((((x => x))), ((x => x)), 10); // Ternaries in parens var i = fun((Math.random() < 0.5 ? x => x : x => undefined), 10); ->i : unknown ->fun((Math.random() < 0.5 ? x => x : x => undefined), 10) : unknown +>i : number +>fun((Math.random() < 0.5 ? x => x : x => undefined), 10) : number >fun : { (g: (x: T) => T, x: T): T; (g: (x: T_1) => T_1, h: (y: T_1) => T_1, x: T_1): T_1; } ->(Math.random() < 0.5 ? x => x : x => undefined) : (x: unknown) => any ->Math.random() < 0.5 ? x => x : x => undefined : (x: unknown) => any +>(Math.random() < 0.5 ? x => x : x => undefined) : (x: number) => any +>Math.random() < 0.5 ? x => x : x => undefined : (x: number) => any >Math.random() < 0.5 : boolean >Math.random() : number >Math.random : () => number >Math : Math >random : () => number >0.5 : 0.5 ->x => x : (x: unknown) => unknown ->x : unknown ->x : unknown ->x => undefined : (x: unknown) => any ->x : unknown +>x => x : (x: number) => number +>x : number +>x : number +>x => undefined : (x: number) => any +>x : number >undefined : undefined >10 : 10 var j = fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), 10); ->j : unknown ->fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), 10) : unknown +>j : number +>fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), 10) : number >fun : { (g: (x: T) => T, x: T): T; (g: (x: T_1) => T_1, h: (y: T_1) => T_1, x: T_1): T_1; } ->(Math.random() < 0.5 ? (x => x) : (x => undefined)) : (x: unknown) => any ->Math.random() < 0.5 ? (x => x) : (x => undefined) : (x: unknown) => any +>(Math.random() < 0.5 ? (x => x) : (x => undefined)) : (x: number) => any +>Math.random() < 0.5 ? (x => x) : (x => undefined) : (x: number) => any >Math.random() < 0.5 : boolean >Math.random() : number >Math.random : () => number >Math : Math >random : () => number >0.5 : 0.5 ->(x => x) : (x: unknown) => unknown ->x => x : (x: unknown) => unknown ->x : unknown ->x : unknown ->(x => undefined) : (x: unknown) => any ->x => undefined : (x: unknown) => any ->x : unknown +>(x => x) : (x: number) => number +>x => x : (x: number) => number +>x : number +>x : number +>(x => undefined) : (x: number) => any +>x => undefined : (x: number) => any +>x : number >undefined : undefined >10 : 10 var k = fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), x => x, 10); ->k : unknown ->fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), x => x, 10) : unknown +>k : number +>fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), x => x, 10) : number >fun : { (g: (x: T) => T, x: T): T; (g: (x: T_1) => T_1, h: (y: T_1) => T_1, x: T_1): T_1; } ->(Math.random() < 0.5 ? (x => x) : (x => undefined)) : (x: unknown) => any ->Math.random() < 0.5 ? (x => x) : (x => undefined) : (x: unknown) => any +>(Math.random() < 0.5 ? (x => x) : (x => undefined)) : (x: number) => any +>Math.random() < 0.5 ? (x => x) : (x => undefined) : (x: number) => any >Math.random() < 0.5 : boolean >Math.random() : number >Math.random : () => number >Math : Math >random : () => number >0.5 : 0.5 ->(x => x) : (x: unknown) => unknown ->x => x : (x: unknown) => unknown ->x : unknown ->x : unknown ->(x => undefined) : (x: unknown) => any ->x => undefined : (x: unknown) => any ->x : unknown +>(x => x) : (x: number) => number +>x => x : (x: number) => number +>x : number +>x : number +>(x => undefined) : (x: number) => any +>x => undefined : (x: number) => any +>x : number >undefined : undefined ->x => x : (x: unknown) => unknown ->x : unknown ->x : unknown +>x => x : (x: number) => number +>x : number +>x : number >10 : 10 var l = fun(((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))), ((x => x)), 10); ->l : unknown ->fun(((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))), ((x => x)), 10) : unknown +>l : number +>fun(((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))), ((x => x)), 10) : number >fun : { (g: (x: T) => T, x: T): T; (g: (x: T_1) => T_1, h: (y: T_1) => T_1, x: T_1): T_1; } ->((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))) : (x: unknown) => any ->(Math.random() < 0.5 ? ((x => x)) : ((x => undefined))) : (x: unknown) => any ->Math.random() < 0.5 ? ((x => x)) : ((x => undefined)) : (x: unknown) => any +>((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))) : (x: number) => any +>(Math.random() < 0.5 ? ((x => x)) : ((x => undefined))) : (x: number) => any +>Math.random() < 0.5 ? ((x => x)) : ((x => undefined)) : (x: number) => any >Math.random() < 0.5 : boolean >Math.random() : number >Math.random : () => number >Math : Math >random : () => number >0.5 : 0.5 ->((x => x)) : (x: unknown) => unknown ->(x => x) : (x: unknown) => unknown ->x => x : (x: unknown) => unknown ->x : unknown ->x : unknown ->((x => undefined)) : (x: unknown) => any ->(x => undefined) : (x: unknown) => any ->x => undefined : (x: unknown) => any ->x : unknown +>((x => x)) : (x: number) => number +>(x => x) : (x: number) => number +>x => x : (x: number) => number +>x : number +>x : number +>((x => undefined)) : (x: number) => any +>(x => undefined) : (x: number) => any +>x => undefined : (x: number) => any +>x : number >undefined : undefined ->((x => x)) : (x: unknown) => unknown ->(x => x) : (x: unknown) => unknown ->x => x : (x: unknown) => unknown ->x : unknown ->x : unknown +>((x => x)) : (x: number) => number +>(x => x) : (x: number) => number +>x => x : (x: number) => number +>x : number +>x : number >10 : 10 var lambda1: (x: number) => number = x => x; diff --git a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt index fe264fff22813..d969c7858a5f7 100644 --- a/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt +++ b/tests/baselines/reference/tsxStatelessFunctionComponentOverload5.errors.txt @@ -6,8 +6,7 @@ file.tsx(48,13): error TS2769: No overload matches this call. Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. Overload 3 of 3, '(hyphenProps: HyphenProps): Element', gave the following error. - Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. - Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. + Property '"data-format"' is missing in type '{ children: string; to: string; onClick: {}; }' but required in type 'HyphenProps'. file.tsx(54,51): error TS2769: No overload matches this call. Overload 1 of 3, '(buttonProps: ButtonProps): Element', gave the following error. Type 'number' is not assignable to type 'string'. @@ -91,8 +90,8 @@ file.tsx(56,13): error TS2769: No overload matches this call. !!! error TS2769: Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & LinkProps'. !!! error TS2769: Property 'onClick' does not exist on type 'IntrinsicAttributes & LinkProps'. !!! error TS2769: Overload 3 of 3, '(hyphenProps: HyphenProps): Element', gave the following error. -!!! error TS2769: Type '{ children: string; to: string; onClick: (e: any) => void; }' is not assignable to type 'IntrinsicAttributes & HyphenProps'. -!!! error TS2769: Property 'to' does not exist on type 'IntrinsicAttributes & HyphenProps'. +!!! error TS2769: Property '"data-format"' is missing in type '{ children: string; to: string; onClick: {}; }' but required in type 'HyphenProps'. +!!! related TS2728 file.tsx:17:5: '"data-format"' is declared here. !!! related TS2793 file.tsx:38:17: The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible. const b1 = {}} {...obj0}>Hello world; // extra property; const b2 = ; // extra property diff --git a/tests/cases/compiler/functionOverloadInformsPriorArgumentType.ts b/tests/cases/compiler/functionOverloadInformsPriorArgumentType.ts new file mode 100644 index 0000000000000..ee42dae02fd29 --- /dev/null +++ b/tests/cases/compiler/functionOverloadInformsPriorArgumentType.ts @@ -0,0 +1,23 @@ +// @strict: true + +enum ModifierFlags { + None = 0, + In = 1, + Out = 2, + Const = 4, + Other = 8, +} + +interface Declaration { + modifierFlags: ModifierFlags; +} + +declare function getEffectiveModifierFlags(d: Declaration): ModifierFlags; + +declare function reduceLeft(array: readonly T[] | undefined, f: (memo: U, value: T, i: number) => U, initial: U, start?: number, count?: number): U; +// only has an issue when the 2nd overload is present, even though it has an arity mismatch +declare function reduceLeft(array: readonly T[], f: (memo: T, value: T, i: number) => T): T | undefined; + +function getTypeParameterModifiers(declarations: Declaration[]): ModifierFlags { + return reduceLeft(declarations, (modifiers, d) => modifiers | getEffectiveModifierFlags(d), ModifierFlags.None) & (ModifierFlags.In | ModifierFlags.Out | ModifierFlags.Const); +} \ No newline at end of file From dd829c48ea3c7b4546dc23f1dbc30626b1b09b74 Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 11 Mar 2024 12:29:33 -0700 Subject: [PATCH 17/18] Use lazy speculatable map for relationship caches to reduce eager copy overhead --- src/compiler/checker.ts | 93 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b0ff4e43ec52f..529547426f1ce 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1695,6 +1695,87 @@ export class NodeLinks extends SpeculatableLinks { declare fakeScopeForSignatureDeclaration?: "params" | "typeParams"; } +/** + * SpeculatableMap is like a Map, except it lazily follows the speculation state of the host + * + * Also, it doesn't support `.delete` or `.clear` - not because it couldn't, buit just because + * the use for this (relationship caches), doesn't use either feature of `Map`s. + */ +class SpeculatableMap implements Map { + private innerMap = new Map(); + constructor(public host: SpeculationHost) {} + + private getCurrentStateFromList(key: K, valueList: [epoch: number, value: V][]): [exists: boolean, value: V] { + const discarded = this.host.getDiscardedSpeculativeEpochs(); + let unwrappedValue: V | undefined; + let exists = false; + for (let i = valueList.length - 1; i >= 0; i--) { + const [epoch, value] = valueList[i]; + if (discarded.has(epoch)) { + valueList.splice(i, 1); + if (valueList.length === 0) { + this.innerMap.delete(key); + break; + } + continue; + } + unwrappedValue = value; + exists = true; + break; + } + return [exists, unwrappedValue!]; + } + + get(key: K): V | undefined { + const valueList = this.innerMap.get(key); + if (!valueList || !valueList.length) return undefined; + const [ exists, unwrappedValue ] = this.getCurrentStateFromList(key, valueList); + if (!exists) return undefined; + return unwrappedValue; + } + has(key: K): boolean { + const valueList = this.innerMap.get(key); + if (!valueList || !valueList.length) return false; + const [ exists, _unwrappedValue ] = this.getCurrentStateFromList(key, valueList); + return exists; + } + set(key: K, value: V): this { + const valueList = this.innerMap.get(key) || this.innerMap.set(key, []).get(key)!; + valueList.push([ this.host.getCurrentSpeculativeEpoch(), value ]); + return this; + } + /** + * Approximate - does not include lazy removals + */ + get size(): number { + return this.innerMap.size; + } + + // These methods are unimplemented mostly because they're thus-far unused. + declare clear: never; + declare delete: never; + declare entries: never; + declare values: never; + declare [globalThis.Symbol.iterator]: never; + + // Implemented just to provide utlity when debugging + forEach(callbackfn: (value: V, key: K, map: Map) => void, thisArg?: any): void { + return this.innerMap.forEach((valueList, k, _inner) => { + const [ exists, unwrappedValue ] = this.getCurrentStateFromList(k, valueList); + if (exists) { + return callbackfn.call(thisArg, unwrappedValue, k, this); + } + }); + } + + // Likewise, provided for debuggability + keys(): IterableIterator { + return this.innerMap.keys(); + } + + [globalThis.Symbol.toStringTag] = SpeculatableMap.name; +} + /** @internal */ export function getNodeId(node: Node): number { if (!node.id) { @@ -2586,12 +2667,12 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { // Relationship caches need to be speculative so we can un-upgrade "ErrorAndReported" results back down, since we're rewinding the error // Otherwise, we think we've emitted lots of elaboration that we just swallow up in discarded speculative contexts - var subtypeRelation = registerSpeculativeCache(new Map()); - var strictSubtypeRelation = registerSpeculativeCache(new Map()); - var assignableRelation = registerSpeculativeCache(new Map()); - var comparableRelation = registerSpeculativeCache(new Map()); - var identityRelation = registerSpeculativeCache(new Map()); - var enumRelation = registerSpeculativeCache(new Map()); + var subtypeRelation = new SpeculatableMap(speculationHost); + var strictSubtypeRelation = new SpeculatableMap(speculationHost); + var assignableRelation = new SpeculatableMap(speculationHost); + var comparableRelation = new SpeculatableMap(speculationHost); + var identityRelation = new SpeculatableMap(speculationHost); + var enumRelation = new SpeculatableMap(speculationHost); var builtinGlobals = createSymbolTable(); builtinGlobals.set(undefinedSymbol.escapedName, undefinedSymbol); From bca2687513de5319f6a2635ef24f17ac9a49e25b Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 11 Mar 2024 12:34:58 -0700 Subject: [PATCH 18/18] Sanity check assert, formatting --- src/compiler/checker.ts | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index c8d09afe34ad7..fd3d88721b1d4 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -1697,7 +1697,7 @@ export class NodeLinks extends SpeculatableLinks { /** * SpeculatableMap is like a Map, except it lazily follows the speculation state of the host - * + * * Also, it doesn't support `.delete` or `.clear` - not because it couldn't, buit just because * the use for this (relationship caches), doesn't use either feature of `Map`s. */ @@ -1729,19 +1729,19 @@ class SpeculatableMap implements Map { get(key: K): V | undefined { const valueList = this.innerMap.get(key); if (!valueList || !valueList.length) return undefined; - const [ exists, unwrappedValue ] = this.getCurrentStateFromList(key, valueList); + const [exists, unwrappedValue] = this.getCurrentStateFromList(key, valueList); if (!exists) return undefined; return unwrappedValue; } has(key: K): boolean { const valueList = this.innerMap.get(key); if (!valueList || !valueList.length) return false; - const [ exists, _unwrappedValue ] = this.getCurrentStateFromList(key, valueList); + const [exists, _unwrappedValue] = this.getCurrentStateFromList(key, valueList); return exists; } set(key: K, value: V): this { const valueList = this.innerMap.get(key) || this.innerMap.set(key, []).get(key)!; - valueList.push([ this.host.getCurrentSpeculativeEpoch(), value ]); + valueList.push([this.host.getCurrentSpeculativeEpoch(), value]); return this; } /** @@ -1761,7 +1761,7 @@ class SpeculatableMap implements Map { // Implemented just to provide utlity when debugging forEach(callbackfn: (value: V, key: K, map: Map) => void, thisArg?: any): void { return this.innerMap.forEach((valueList, k, _inner) => { - const [ exists, unwrappedValue ] = this.getCurrentStateFromList(k, valueList); + const [exists, unwrappedValue] = this.getCurrentStateFromList(k, valueList); if (exists) { return callbackfn.call(thisArg, unwrappedValue, k, this); } @@ -49213,6 +49213,9 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker { } function registerSpeculativeCache(collection: T): T { + if (collection instanceof SpeculatableMap) { + return Debug.fail("Collection is already inherently speculatable, no need to globally register."); + } speculativeCaches.push(collection); return collection; }