Skip to content

Commit d52d9d9

Browse files
authored
🤖 Merge PR DefinitelyTyped#71578 phoenix_live_view 1.0, metadata LiveSocket option by @pzingg
1 parent 42bb005 commit d52d9d9

File tree

12 files changed

+832
-457
lines changed

12 files changed

+832
-457
lines changed

‎types/phoenix_live_view/README.md‎

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,26 +8,33 @@ This package contains the type definitions for the [Phoenix LiveView](https://gi
88
npm install --save-dev @types/phoenix_live_view
99
```
1010

11-
## BREAKING CHANGE in 0.20.0
11+
## BREAKING CHANGE in 0.20 and 1.0
1212

13-
The `ViewHook` interface has been modified to better reflect the type expected by developers writing their own hooks. It used to correspond to the type of the hook object as it is constructed by the Phoenix LiveView library internally, but it included properties which are not expected for developers to provide. This required casting or commenting to make the typescript compiler happy when declaring hooks.
13+
To preserve the actual namespaces of the phoenix_live_view Javascript modules, we distinguish
14+
three different exports:
1415

15-
The new `ViewHook` interface is now correct and only expects the hook functions that developers are expected to provide given the public API. But it still provides the previous interface as `ViewHookInternal` for those who need to use it.
16+
* `ViewHookInterface` is the interface (contract) for a LiveView hook.
17+
* `ViewHook` is the implemented class in the phoenix_live_view module that implements
18+
`ViewHookInterface`
19+
* `Hook` is the generic interface that uses intersection types to let developers
20+
add additional functionality to an instance of a hook.
1621

17-
Besides, and it correctly assigns the `ViewHookInternal` type to `this` when writing a hook, so properties like `el`, `viewName`, and functions like `push_event` are all there. The `ViewHook` interface can also now be used as a generic for developers who want to assign their own functions and properties to the hook object.
22+
The `Hook` interface only expects the hook functions that developers are expected to provide given the public API.
23+
24+
`Hook` correctly assigns the `ViewHookInterface` interface to `this` when writing a hook, so properties like `el` and functions like `push_event` are all there. The `Hook` interface can also now be used as a generic for developers who want to assign their own functions and properties to the hook object.
1825

1926
```typescript
20-
const testHook: ViewHook = {
27+
const testHook: Hook = {
2128
mounted() {
2229
const hook = this;
23-
console.log("TestHook mounted", { element: this.el, viewName: this.viewName });
24-
hook.pushEvent("hook-mounted", { name: "testHook" }, (reply, ref) => {
30+
console.log("TestHook mounted", { element: this.el });
31+
hook.pushEvent("hook-mounted", { name: "testHook" }, (reply: object, ref: number) => {
2532
console.log(`Got hook-mounted reply ${JSON.stringify(reply)} ref ${ref}`);
2633
});
2734
},
2835
};
2936

30-
const testHookWithExtendedPrototype: ViewHook<{ handleClick: (event: MouseEvent) => void }> = {
37+
const testHookWithExtendedPrototype: Hook<{ handleClick: (event: MouseEvent) => void }> = {
3138
mounted() {
3239
this.handleClick = (event: MouseEvent) => {
3340
console.log("click", event);
@@ -46,6 +53,5 @@ const MyHooks: HooksOptions = {
4653
};
4754

4855
const liveSocket = new LiveSocket("/live", Socket, opts);
49-
5056
```
5157

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import LiveSocket from "./live_socket";
2+
3+
export type OnReply = (reply: any, ref: number) => any;
4+
export type CallbackRef = (customEvent: any, bypass: boolean) => string;
5+
6+
export interface ViewHookInterface {
7+
el: HTMLElement;
8+
liveSocket: LiveSocket;
9+
10+
mounted?: () => void;
11+
updated?: () => void;
12+
beforeUpdate?: () => void;
13+
destroyed?: () => void;
14+
reconnected?: () => void;
15+
disconnected?: () => void;
16+
17+
js(): object;
18+
pushEvent(event: string, payload: any, onReply?: OnReply): any;
19+
pushEventTo(phxTarget: any, event: string, payload: object, onReply?: OnReply): any;
20+
handleEvent(event: string, callback: any): CallbackRef;
21+
removeHandleEvent(callbackRef: CallbackRef): void;
22+
upload(name: any, files: any): any;
23+
uploadTo(phxTarget: any, name: any, files: any): any;
24+
}
25+
26+
export interface Hook<T extends object = {}> {
27+
mounted?: (this: T & ViewHookInterface) => void;
28+
beforeUpdate?: (this: T & ViewHookInterface) => void;
29+
updated?: (this: T & ViewHookInterface) => void;
30+
beforeDestroy?: (this: T & ViewHookInterface) => void;
31+
destroyed?: (this: T & ViewHookInterface) => void;
32+
disconnected?: (this: T & ViewHookInterface) => void;
33+
reconnected?: (this: T & ViewHookInterface) => void;
34+
}
35+
36+
export type HooksOptions = Record<string, Hook<any>>;

0 commit comments

Comments
 (0)