Repository navigation
silentNeverType leak through return type inferenceΒ #62824
Copy link
Copy link
Open
Labels
BugA bug in TypeScriptA bug in TypeScriptDomain: check: Type InferenceRelated to type inference performed during signature resolution or `infer` type resolutionRelated to type inference performed during signature resolution or `infer` type resolutionHelp WantedYou can do thisYou can do this
Milestone
Description
Activity
- addedBugA bug in TypeScriptA bug in TypeScriptHelp WantedYou can do thisYou can do this
on Dec 3, 2025 RyanCavanaugh commented
on Dec 3, 2025 MemberMore actionsIs there a simpler test a mere mortal like me can understand?
Reacted by Martin JohnsAndarist commented
on Dec 3, 2025 ContributorAuthorMore actionsCome on, Ryan, I know you know I know youβre not a mere mortal.
A shorter repro would be this:
type Values<T> = T[keyof T]; interface ParameterizedObject { type: string; params?: unknown; } type ActionFunction<TParams, TAction extends ParameterizedObject> = { (params: TParams): void; _out_TAction?: TAction; }; type ToParameterizedObject<TParameterizedMap> = Values<{ [K in keyof TParameterizedMap & string]: { type: K; params: TParameterizedMap[K]; }; }>; declare function enqueueActions<TParams, TAction extends ParameterizedObject>( collect: (params: TParams) => void, ): ActionFunction<TParams, TAction>; declare function setup<TActions>(actions: { [K in keyof TActions]: ActionFunction< TActions[K], ToParameterizedObject<TActions> >; }): void; setup({ doStuff: enqueueActions((params: number) => {}), });
And a minimal (but totally non-sensical) would be something like this:
type Fn<T> = (arg: T) => void; declare function fn1<T>(): Fn<T>; declare function fn2<T>( ac: Fn<{ [K in keyof T & string]: T[K]; }>, ): void; fn2(fn1());
The key here is that the inner call gets
silentNeverTypein its return type inference pass from the outer mapper as at that time there is no inference candidate forT. Thenkeyof silentNeverTypemanages to "transform" it (so it manages to "escape") and boxes it in another type (the result of this mapped type):keyof silentNeverType // string | number | symbolkeyof silentNeverType & string // stringsilentNeverType[K] // silentNeverType{ [K in keyof silentNeverType & string]: silentNeverType[K]; } // { [k: string]: silentNeverType }
Reacted by Ryan Cavanaugh- addedDomain: check: Type InferenceRelated to type inference performed during signature resolution or `infer` type resolutionRelated to type inference performed during signature resolution or `infer` type resolution
on Dec 9, 2025
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScriptDomain: check: Type InferenceRelated to type inference performed during signature resolution or `infer` type resolutionRelated to type inference performed during signature resolution or `infer` type resolutionHelp WantedYou can do thisYou can do this
π Search Terms
silent never leak reverse mapped types nested calls return type inference
π Version & Regression Information
β― Playground Link
https://www.typescriptlang.org/play/?noEmit=true&ts=6.0.0-dev.20251202#code/C4TwDgpgBAaghgGwK4QM4B4AqA+KBeKTAbQGsIQB7AM0IF0BuAKEdEigFk4BjACwEsAdhADCFAcAgAPYPigAlCFwoAnACbpUwZYIDmAGihwBIbE0aCJyqt2gAFOMrgBbCJb4AvCKoDyAIwBWijIA3oxQUKwQAFxQmtoCOkzhYA7OqAD8MUgCJAIUAO4CTAC+zJFQAIJcwHxiAGLZ1bUC6GGEouJSMl0QAqqoHNz8Qh0S0nptmPaOTgM9fQPTzq4Q2p4+AUFEAEQpM6jbtFAAPlDZqhBUgl4T4ZhVNWJQ8-1QSy5u636B1RO4BKFwgAKaqSGKYUZdAx7NLg96oACUMQAbhQ+KoklAAPoUJDALH3JpiTKEB7NEpmcqYCjvFZrLzfIKtO60z5eThgZ7SXqvBRKNTM8KxLS6W5C1mrDwMzbVHYw2aHE5nPqXa6qNrYP6yeDINDoQFQIgAaSggigZEoNCmqQ+kvWHKgADJhfEdLQYgbwpEYkbMckbag4Ta6VLVBzjQw2sUSqYyuBoKIEAggmSxBhJpDpFyJAtBrxrpngGLrftszzFsG2RsfsA5QHFadzqqhKotQQgW1PVAlJ1xm1wr0AI4oFBi4oe-vdsRjYDgwt+54CYcQFAxIHcR4CNcI-C4VHond4PdojFRsXywOEeETQ-H9FmC5cBAOaBURqbxfLlCpgTpu6Fstc04fMRmnKFJnhQDXglelqy2XZ6yORsVSuFtix-KCKxmEMvhlGQCBg0NGV+RhsA7cIlCTIIYkTZNqh-DAITA8YrwDTVGCRSoiQEBoBG4rBCwMEs0iEn9Y0YR9n2UV932aWJXCQMBBSY3tum5IChgLZii0mBjMPkRQVHUSc4lFSdCNwms632BtlQuVCvA1WRgmKP4gQNSJUDFDdmi8xhxygDz4wyD0p1UkkVJnKBozaHy0xJLtjVNARzXIahSW41B3S4zdeP4yd-20sUhQyzdUAjYqhWpCzpRrLAGOwSdY3CGLik4-dT0YVAFLAdzYsyicStUCgAGVgCQKgqBiIcRwgBigSBLFoQDGIBCQJxfFWW9ArascJjasxuvG3qDTi39BqFYaxomqbP1m+bFuW-ZVvWzblG2lyEUq4bvGAHhVmuya1yWqALxiUyEg+1yz38hFDp6vrwjOy8uyu8agbulc5syhaQbBqA1o2rbdx2r7Jx+v6AfR27FpiIwQCe2EXV0KG9thpggA
π» Code
π Actual behavior
First 2 calls mention such a relationship check failure in the error message:
Notice never there. This is quite weird an unexpected as there is no
neverin sight here. It turns out this is asilentNeverTypethat leaked through.π Expected behavior
At the very least, I would expect it to error with consistent error messages mentioning
unknowninstead ofnever. Even better, if it could behave closer to a very similar version of this code: TS playground. In there the third error still errors but the first two infers nicely.Additional information about the issue
No response