Skip to content

Commit 602daaa

Browse files
committed
fix(linter/plugins): fix type definition for VisitorObject (#20065)
Fixes #18154, #14745. Use the bivariance hack to fix the type def for `VisitorObject`. The bivariance hack is taken from DefinitelyTyped/DefinitelyTyped#20219. This was originally written by @sapphi-red in #19675. I've split it out into a separate PR. I can't claim to understand this witchcraft!
1 parent ee0491e commit 602daaa

File tree

2 files changed

+22
-4
lines changed

2 files changed

+22
-4
lines changed

apps/oxlint/src-js/generated/visitor.d.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,11 @@
33

44
import type * as ESTree from "./types.d.ts";
55

6-
export interface VisitorObject {
6+
type BivarianceHackHandler<Handler extends (...args: any) => any> = {
7+
bivarianceHack(...args: Parameters<Handler>): ReturnType<Handler>;
8+
}["bivarianceHack"];
9+
10+
interface StrictVisitorObject {
711
DebuggerStatement?: (node: ESTree.DebuggerStatement) => void;
812
"DebuggerStatement:exit"?: (node: ESTree.DebuggerStatement) => void;
913
EmptyStatement?: (node: ESTree.EmptyStatement) => void;
@@ -384,5 +388,10 @@ export interface VisitorObject {
384388
"TSTypeReference:exit"?: (node: ESTree.TSTypeReference) => void;
385389
TSUnionType?: (node: ESTree.TSUnionType) => void;
386390
"TSUnionType:exit"?: (node: ESTree.TSUnionType) => void;
387-
[key: string]: (node: ESTree.Node) => void;
388391
}
392+
393+
export type VisitorObject = {
394+
[K in keyof StrictVisitorObject]?:
395+
| BivarianceHackHandler<Exclude<StrictVisitorObject[K], undefined>>
396+
| undefined;
397+
} & Record<string, BivarianceHackHandler<(node: ESTree.Node) => void> | undefined>;

tasks/ast_tools/src/generators/estree_visit.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -507,13 +507,22 @@ fn generate(codegen: &Codegen) -> Codes {
507507
}}
508508
");
509509

510+
// See https://github.com/DefinitelyTyped/DefinitelyTyped/pull/20219 for why we need "Bivariance hack"
510511
#[rustfmt::skip]
511512
let visitor_type_oxlint = format!("
512513
import type * as ESTree from './types.d.ts';
513514
514-
export interface VisitorObject {{
515-
{visitor_type} [key: string]: (node: ESTree.Node) => void;
515+
type BivarianceHackHandler<Handler extends (...args: any) => any> = {{
516+
bivarianceHack(...args: Parameters<Handler>): ReturnType<Handler>;
517+
}}[\"bivarianceHack\"];
518+
519+
interface StrictVisitorObject {{
520+
{visitor_type}
516521
}}
522+
523+
export type VisitorObject = {{
524+
[K in keyof StrictVisitorObject]?: BivarianceHackHandler<Exclude<StrictVisitorObject[K], undefined>> | undefined;
525+
}} & Record<string, BivarianceHackHandler<(node: ESTree.Node) => void> | undefined>;
517526
");
518527

519528
// Type definitions for walk.js.

0 commit comments

Comments
 (0)