Skip to content

Feature implementation from commits b86ab7d..5a3271b #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 25 commits into
base: feature-base-branch-1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
81c9518
Fix getResolvePackageJsonImports utility (#61707)
andrewbranch May 16, 2025
b504a1e
Handle lock file 3 version when caching the typings ensuring we can r…
sheetalkamat May 21, 2025
44d4671
Update pr_owners.txt (#61798)
jakebailey Jun 3, 2025
3dd0a35
Initialize the map for dts to reference and source to reference when …
sheetalkamat Jun 4, 2025
2b88aeb
LEGO: Pull request from lego/hb_5378966c-b857-470a-8675-daebef4a6da1_…
csigs Jun 4, 2025
a591ca3
fix(61747): for (using of = is incorrectly parsed (#61764)
a-tarasyuk Jun 5, 2025
ac03ba4
fix(checker): report error when using bigint as enum key (#61777)
magic-akari Jun 5, 2025
cd34199
tsc --init update (#61813)
RyanCavanaugh Jun 6, 2025
a69c6d0
Add support for `import defer` proposal (#60757)
nicolo-ribaudo Jun 6, 2025
ffd98c1
feat: add Error.isError() to ESNext lib (#60788)
dirkluijk Jun 6, 2025
51dcd90
Cache mapper instantiations (#61505)
Andarist Jun 6, 2025
652ed7f
Add lib.esnext.sharedmemory (#61646)
Renegade334 Jun 6, 2025
1e24945
explicitly disallow `using` in ambient contexts (#61781)
Renegade334 Jun 6, 2025
fa2a0fc
Issue "'{0}' declarations can only be declared inside a block." for b…
Andarist Jun 6, 2025
7715955
Fix helpers emit for .cjs files in ESM module mode (#61814)
andrewbranch Jun 6, 2025
355b9e0
Avoid resolving source prop type when the target is `unknown`/`any` (…
Andarist Jun 6, 2025
97cfa26
optimization, reduce memory usage (#61822)
VincentBailly Jun 9, 2025
cb38d99
Add `--module node20` (#61805)
andrewbranch Jun 9, 2025
34d1ea6
Fix type variable leaks and cache inconsistencies (#61668)
ahejlsberg Jun 9, 2025
0dfd0c2
Restore `import defer =` parsing (#61837)
nicolo-ribaudo Jun 9, 2025
12e09f4
Port "Improve type discrimination algorithm" from tsgo (#61828)
jakebailey Jun 9, 2025
529ed09
fix link to "Help Wanted" issues (#61843)
AllenSH12 Jun 11, 2025
dd1e258
LEGO: Pull request from lego/hb_5378966c-b857-470a-8675-daebef4a6da1_…
csigs Jun 11, 2025
f1d2494
LEGO: Pull request from lego/hb_5378966c-b857-470a-8675-daebef4a6da1_…
csigs Jun 17, 2025
5a3271b
LEGO: Pull request from lego/hb_5378966c-b857-470a-8675-daebef4a6da1_…
csigs Jun 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix type variable leaks and cache inconsistencies (microsoft#61668)
  • Loading branch information
ahejlsberg authored Jun 9, 2025
commit 34d1ea68f6ef83689909ab77a625c177887d09b1
114 changes: 37 additions & 77 deletions src/compiler/checker.ts

Large diffs are not rendered by default.

12 changes: 2 additions & 10 deletions src/compiler/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6539,7 +6539,7 @@ export const enum ObjectFlags {
CouldContainTypeVariablesComputed = 1 << 19, // CouldContainTypeVariables flag has been computed
/** @internal */
CouldContainTypeVariables = 1 << 20, // Type could contain a type variable

SingleSignatureType = 1 << 27, // A single signature type extracted from a potentially broader type
ClassOrInterface = Class | Interface,
/** @internal */
RequiresWidening = ContainsWideningType | ContainsObjectOrArrayLiteral,
Expand All @@ -6555,7 +6555,6 @@ export const enum ObjectFlags {
ContainsSpread = 1 << 21, // Object literal contains spread operation
ObjectRestType = 1 << 22, // Originates in object rest declaration
InstantiationExpressionType = 1 << 23, // Originates in instantiation expression
SingleSignatureType = 1 << 27, // A single signature type extracted from a potentially broader type
/** @internal */
IsClassInstanceClone = 1 << 24, // Type is a clone of a class instance type
// Flags that require TypeFlags.Object and ObjectFlags.Reference
Expand Down Expand Up @@ -6770,12 +6769,6 @@ export interface AnonymousType extends ObjectType {
instantiations?: Map<string, Type>; // Instantiations of generic type alias (undefined if non-generic)
}

/** @internal */
// A SingleSignatureType may have bespoke outer type parameters to handle free type variable inferences
export interface SingleSignatureType extends AnonymousType {
outerTypeParameters?: TypeParameter[];
}

/** @internal */
export interface InstantiationExpressionType extends AnonymousType {
node: NodeWithTypeArguments;
Expand Down Expand Up @@ -7061,8 +7054,6 @@ export interface Signature {
isolatedSignatureType?: ObjectType; // A manufactured type that just contains the signature for purposes of signature comparison
/** @internal */
instantiations?: Map<string, Signature>; // Generic signature instantiation cache
/** @internal */
implementationSignatureCache?: Signature; // Copy of the signature with fresh type parameters to use in checking the body of a potentially self-referential generic function (deferred)
}

export const enum IndexKind {
Expand Down Expand Up @@ -7170,6 +7161,7 @@ export interface InferenceContext {
mapper: TypeMapper; // Mapper that fixes inferences
nonFixingMapper: TypeMapper; // Mapper that doesn't fix inferences
returnMapper?: TypeMapper; // Type mapper for inferences from return types (if any)
outerReturnMapper?: TypeMapper; // Type mapper for inferences from return types of outer function (if any)
inferredTypeParameters?: readonly TypeParameter[]; // Inferred type parameters for function result
intraExpressionInferenceSites?: IntraExpressionInferenceSite[];
}
Expand Down
2 changes: 1 addition & 1 deletion tests/baselines/reference/api/typescript.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6717,11 +6717,11 @@ declare namespace ts {
JSLiteral = 4096,
FreshLiteral = 8192,
ArrayLiteral = 16384,
SingleSignatureType = 134217728,
ClassOrInterface = 3,
ContainsSpread = 2097152,
ObjectRestType = 4194304,
InstantiationExpressionType = 8388608,
SingleSignatureType = 134217728,
}
interface ObjectType extends Type {
objectFlags: ObjectFlags;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
//// [tests/cases/compiler/genericCallInferenceInConditionalTypes1.ts] ////

=== genericCallInferenceInConditionalTypes1.ts ===
// https://github.com/microsoft/TypeScript/issues/59937

type Ref<T> = {
>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 2, 9))

current: T;
>current : Symbol(current, Decl(genericCallInferenceInConditionalTypes1.ts, 2, 15))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 2, 9))

};

type FunctionComponent<P> = (props: P) => unknown;
>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 23))
>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 29))
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 23))

type ComponentProps<T extends FunctionComponent<any>> =
>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 8, 20))
>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))

T extends FunctionComponent<infer P> ? P : {};
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 8, 20))
>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 35))
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 35))

type PropsWithoutRef<P> = P extends any
>PropsWithoutRef : Symbol(PropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 48))
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))

? "ref" extends keyof P
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))

? Omit<P, "ref">
>Omit : Symbol(Omit, Decl(lib.es5.d.ts, --, --))
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))

: P
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))

: P;
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 11, 21))

type ComponentPropsWithoutRef<T extends FunctionComponent<any>> =
>ComponentPropsWithoutRef : Symbol(ComponentPropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 15, 6))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 17, 30))
>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))

PropsWithoutRef<ComponentProps<T>>;
>PropsWithoutRef : Symbol(PropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 48))
>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 17, 30))

declare function forwardRef<T, P>(
>forwardRef : Symbol(forwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 18, 37))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 28))
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 30))

component: (props: P, ref: Ref<T>) => unknown,
>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 34))
>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 21, 14))
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 30))
>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 21, 23))
>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 28))

): (props: P & { ref?: Ref<T> }) => unknown;
>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 22, 4))
>P : Symbol(P, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 30))
>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 22, 16))
>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 20, 28))

const ComponentWithForwardRef = forwardRef(
>ComponentWithForwardRef : Symbol(ComponentWithForwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 24, 5))
>forwardRef : Symbol(forwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 18, 37))

<T extends FunctionComponent<any>>(
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 25, 3))
>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))

props: ComponentPropsWithoutRef<T>,
>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 25, 37))
>ComponentPropsWithoutRef : Symbol(ComponentPropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 15, 6))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 25, 3))

ref: Ref<HTMLElement>,
>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 26, 39))
>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0))
>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))

) => {
return null;
},
);

type Test<T> = T extends { component?: infer Component }
>Test : Symbol(Test, Decl(genericCallInferenceInConditionalTypes1.ts, 31, 2))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 10))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 10))
>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 26))
>Component : Symbol(Component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 44))

? Component extends FunctionComponent<any>
>Component : Symbol(Component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 44))
>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))

? ComponentProps<Component>
>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
>Component : Symbol(Component, Decl(genericCallInferenceInConditionalTypes1.ts, 33, 44))

: never
: never;

// the first one here has a chance to pollute the cache
type Result1 = ComponentProps<typeof ComponentWithForwardRef>;
>Result1 : Symbol(Result1, Decl(genericCallInferenceInConditionalTypes1.ts, 37, 10))
>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
>ComponentWithForwardRef : Symbol(ComponentWithForwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 24, 5))

// that could be incorrectly reused by this one
type Result2 = Test<{ component: typeof ComponentWithForwardRef }>; // no `T` leak
>Result2 : Symbol(Result2, Decl(genericCallInferenceInConditionalTypes1.ts, 40, 62))
>Test : Symbol(Test, Decl(genericCallInferenceInConditionalTypes1.ts, 31, 2))
>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 42, 21))
>ComponentWithForwardRef : Symbol(ComponentWithForwardRef, Decl(genericCallInferenceInConditionalTypes1.ts, 24, 5))

// same as ComponentWithForwardRef above but using a resolved signature instead of a direct inferred result of `forwardRef`
declare const ComponentWithForwardRef2: <T extends FunctionComponent<any>>(
>ComponentWithForwardRef2 : Symbol(ComponentWithForwardRef2, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 13))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 41))
>FunctionComponent : Symbol(FunctionComponent, Decl(genericCallInferenceInConditionalTypes1.ts, 4, 2))

props: PropsWithoutRef<ComponentProps<T>> & {
>props : Symbol(props, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 75))
>PropsWithoutRef : Symbol(PropsWithoutRef, Decl(genericCallInferenceInConditionalTypes1.ts, 9, 48))
>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 41))

className?: string;
>className : Symbol(className, Decl(genericCallInferenceInConditionalTypes1.ts, 46, 47))

as?: T | undefined;
>as : Symbol(as, Decl(genericCallInferenceInConditionalTypes1.ts, 47, 23))
>T : Symbol(T, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 41))

} & {
ref?: Ref<HTMLElement> | undefined;
>ref : Symbol(ref, Decl(genericCallInferenceInConditionalTypes1.ts, 49, 7))
>Ref : Symbol(Ref, Decl(genericCallInferenceInConditionalTypes1.ts, 0, 0))
>HTMLElement : Symbol(HTMLElement, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))

},
) => unknown;

type Result3 = ComponentProps<typeof ComponentWithForwardRef2>;
>Result3 : Symbol(Result3, Decl(genericCallInferenceInConditionalTypes1.ts, 52, 13))
>ComponentProps : Symbol(ComponentProps, Decl(genericCallInferenceInConditionalTypes1.ts, 6, 50))
>ComponentWithForwardRef2 : Symbol(ComponentWithForwardRef2, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 13))

type Result4 = Test<{ component: typeof ComponentWithForwardRef2 }>;
>Result4 : Symbol(Result4, Decl(genericCallInferenceInConditionalTypes1.ts, 54, 63))
>Test : Symbol(Test, Decl(genericCallInferenceInConditionalTypes1.ts, 31, 2))
>component : Symbol(component, Decl(genericCallInferenceInConditionalTypes1.ts, 55, 21))
>ComponentWithForwardRef2 : Symbol(ComponentWithForwardRef2, Decl(genericCallInferenceInConditionalTypes1.ts, 45, 13))

Loading