Skip to content

Commit 4705ede

Browse files
committed
Infer virtual type definition from renderer arguments.
1 parent 3bdc4b0 commit 4705ede

File tree

2 files changed

+43
-20
lines changed

2 files changed

+43
-20
lines changed

.changeset/quiet-mammals-look.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"haunted": minor
3+
---
4+
5+
Infer `virtual` type definition from renderer arguments.

src/virtual.ts

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,31 @@ import {
33
DirectiveParameters,
44
ChildPart,
55
PartInfo,
6-
} from "lit-html/directive.js";
7-
import { noChange } from "lit-html";
8-
import { AsyncDirective } from "lit-html/async-directive.js";
6+
} from "lit/directive.js";
7+
import { noChange } from "lit";
8+
import { AsyncDirective } from "lit/async-directive.js";
99
import { GenericRenderer } from "./core";
1010
import { BaseScheduler } from "./scheduler";
1111

1212
const includes = Array.prototype.includes;
1313

14-
interface Renderer extends GenericRenderer<ChildPart> {
15-
(this: ChildPart, ...args: unknown[]): unknown | void;
14+
interface Renderer<T extends unknown[]> extends GenericRenderer<ChildPart> {
15+
(this: ChildPart, ...args: T): unknown | void;
1616
}
1717

18-
const partToScheduler: WeakMap<ChildPart, Scheduler> = new WeakMap();
19-
const schedulerToPart: WeakMap<Scheduler, ChildPart> = new WeakMap();
18+
const partToScheduler: WeakMap<ChildPart, Scheduler<any>> = new WeakMap();
19+
const schedulerToPart: WeakMap<Scheduler<any>, ChildPart> = new WeakMap();
2020

21-
class Scheduler extends BaseScheduler<object, ChildPart, Renderer, ChildPart> {
22-
args!: unknown[];
21+
class Scheduler<T extends unknown[]> extends BaseScheduler<
22+
object,
23+
ChildPart,
24+
Renderer<T>,
25+
ChildPart
26+
> {
27+
args!: T;
2328
setValue: Function;
2429

25-
constructor(renderer: Renderer, part: ChildPart, setValue: Function) {
30+
constructor(renderer: Renderer<T>, part: ChildPart, setValue: Function) {
2631
super(renderer, part);
2732
this.state.virtual = true;
2833
this.setValue = setValue;
@@ -43,10 +48,19 @@ class Scheduler extends BaseScheduler<object, ChildPart, Renderer, ChildPart> {
4348
}
4449
}
4550

46-
function makeVirtual(): any {
47-
function virtual(renderer: Renderer) {
51+
interface VirtualRenderer<T extends unknown[]> {
52+
(this: ChildPart, ...args: T): unknown | void;
53+
}
54+
export interface Virtual {
55+
<T extends unknown[]>(renderer: VirtualRenderer<T>): (
56+
...values: T
57+
) => unknown;
58+
}
59+
60+
function makeVirtual(): Virtual {
61+
function virtual<T extends unknown[]>(renderer: VirtualRenderer<T>) {
4862
class VirtualDirective extends AsyncDirective {
49-
cont: Scheduler | undefined;
63+
cont: Scheduler<T> | undefined;
5064

5165
constructor(partInfo: PartInfo) {
5266
super(partInfo);
@@ -56,19 +70,23 @@ function makeVirtual(): any {
5670
update(part: ChildPart, args: DirectiveParameters<this>) {
5771
this.cont = partToScheduler.get(part);
5872
if (!this.cont || this.cont.renderer !== renderer) {
59-
this.cont = new Scheduler(renderer, part, (r: unknown) => {
60-
this.setValue(r);
61-
});
73+
this.cont = new Scheduler(
74+
renderer as Renderer<T>,
75+
part,
76+
(r: unknown) => {
77+
this.setValue(r);
78+
}
79+
);
6280
partToScheduler.set(part, this.cont);
6381
schedulerToPart.set(this.cont, part);
6482
teardownOnRemove(this.cont, part);
6583
}
6684
this.cont.args = args;
6785
this.cont.update();
68-
return this.render(args);
86+
return this.render(...args);
6987
}
7088

71-
render(args: unknown) {
89+
render(...args: T) {
7290
return noChange;
7391
}
7492
}
@@ -79,8 +97,8 @@ function makeVirtual(): any {
7997
return virtual;
8098
}
8199

82-
function teardownOnRemove(
83-
cont: BaseScheduler<object, ChildPart, Renderer, ChildPart>,
100+
function teardownOnRemove<T extends unknown[]>(
101+
cont: BaseScheduler<object, ChildPart, Renderer<T>, ChildPart>,
84102
part: ChildPart,
85103
node = part.startNode
86104
): void {

0 commit comments

Comments
 (0)