Skip to content

Commit 5409f66

Browse files
authored
Merge pull request #379 from wooloo26/master
improve types
2 parents 89efa1a + 2ee926d commit 5409f66

File tree

5 files changed

+48
-63
lines changed

5 files changed

+48
-63
lines changed

src/commit.ts

+8-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
import { Ref } from './type'
1+
import { IFiber, Ref } from './type'
22
import { updateElement } from './dom'
33
import { isFn, TAG } from './reconcile'
44

5-
65
export const commit = (fiber: any) => {
76
if (!fiber) {
87
return
@@ -32,24 +31,24 @@ export const commit = (fiber: any) => {
3231
}
3332

3433
const refer = (ref?: Ref<HTMLElement | undefined>, dom?: HTMLElement) => {
35-
if (ref)
36-
isFn(ref) ? ref(dom) : ref.current = dom
34+
if (ref) isFn(ref) ? ref(dom) : (ref.current = dom)
3735
}
3836

39-
const kidsRefer = (kids: any) => {
40-
kids.forEach(kid => {
37+
const kidsRefer = (kids: IFiber[]) => {
38+
kids.forEach((kid) => {
4139
kid.kids && kidsRefer(kid.kids)
4240
refer(kid.ref, null)
4341
})
4442
}
4543

46-
export const removeElement = fiber => {
44+
export const removeElement = (fiber: IFiber) => {
4745
if (fiber.isComp) {
48-
fiber.hooks && fiber.hooks.list.forEach(e => e[2] && e[2]())
46+
fiber.hooks && fiber.hooks.list.forEach((e) => e[2] && e[2]())
4947
fiber.kids.forEach(removeElement)
5048
} else {
49+
// @ts-expect-error
5150
fiber.parentNode.removeChild(fiber.node)
5251
kidsRefer(fiber.kids)
5352
refer(fiber.ref, null)
5453
}
55-
}
54+
}

src/h.ts

+12-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { isStr, arrayfy } from './reconcile'
2-
import { FC, FreElement } from './type'
2+
import { FC, FreNode, FreText, IFiber } from './type'
33

44
// for jsx2
5-
export const h = (type, props: any, ...kids) => {
5+
export const h = (type: string | FC, props: any, ...kids: FreNode[]) => {
66
props = props || {}
77
kids = flat(arrayfy(props.children || kids))
88

@@ -17,10 +17,11 @@ export const h = (type, props: any, ...kids) => {
1717
return createVnode(type, props, key, ref)
1818
}
1919

20-
const some = (x: unknown) => x != null && x !== true && x !== false
20+
const some = <T>(x: T | boolean | null | undefined): x is T =>
21+
x != null && x !== true && x !== false
2122

22-
const flat = (arr: any[], target = []) => {
23-
arr.forEach(v => {
23+
const flat = (arr: FreNode[], target: IFiber[] = []) => {
24+
arr.forEach((v) => {
2425
isArr(v)
2526
? flat(v, target)
2627
: some(v) && target.push(isStr(v) ? createText(v) : v)
@@ -35,14 +36,17 @@ export const createVnode = (type, props, key, ref) => ({
3536
ref,
3637
})
3738

38-
export const createText = (vnode: any) =>
39-
({ type: '#text', props: { nodeValue: vnode + '' } } as FreElement)
39+
export const createText = (vnode: FreText) =>
40+
({ type: '#text', props: { nodeValue: vnode + '' } } as IFiber)
4041

4142
export function Fragment(props) {
4243
return props.children
4344
}
4445

45-
export function memo<T extends object>(fn: FC<T>, compare?: FC<T>['shouldUpdate']) {
46+
export function memo<T extends object>(
47+
fn: FC<T>,
48+
compare?: FC<T>['shouldUpdate']
49+
) {
4650
fn.memo = true
4751
fn.shouldUpdate = compare
4852
return fn

src/hook.ts

+7-7
Original file line numberDiff line numberDiff line change
@@ -22,15 +22,15 @@ export const resetCursor = () => {
2222
cursor = 0
2323
}
2424

25-
export const useState = <T>(initState: T): [T, Dispatch<SetStateAction<T>>] => {
26-
return useReducer(null, initState)
25+
export const useState = <T>(initState: T) => {
26+
return useReducer<T, SetStateAction<T>>(null, initState)
2727
}
2828

2929
export const useReducer = <S, A>(
3030
reducer?: Reducer<S, A>,
3131
initState?: S
3232
): [S, Dispatch<A>] => {
33-
const [hook, current]: [any, IFiber] = getHook<HookReducer>(cursor++)
33+
const [hook, current] = getHook<HookReducer>(cursor++)
3434
if (hook.length === 0) {
3535
hook[0] = initState
3636
hook[1] = (value: A | Dispatch<A>) => {
@@ -45,22 +45,22 @@ export const useReducer = <S, A>(
4545
}
4646
}
4747
}
48-
return hook
48+
return hook as Required<HookReducer>
4949
}
5050

51-
export const useEffect = (cb: EffectCallback, deps?: DependencyList): void => {
51+
export const useEffect = (cb: EffectCallback, deps?: DependencyList) => {
5252
return effectImpl(cb, deps!, 'effect')
5353
}
5454

55-
export const useLayout = (cb: EffectCallback, deps?: DependencyList): void => {
55+
export const useLayout = (cb: EffectCallback, deps?: DependencyList) => {
5656
return effectImpl(cb, deps!, 'layout')
5757
}
5858

5959
const effectImpl = (
6060
cb: EffectCallback,
6161
deps: DependencyList,
6262
key: 'effect' | 'layout'
63-
): void => {
63+
) => {
6464
const [hook, current] = getHook<HookEffect>(cursor++)
6565
if (isChanged(hook[1], deps)) {
6666
hook[0] = cb

src/reconcile.ts

+12-15
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,4 @@
1-
import {
2-
IFiber,
3-
FreElement,
4-
FC,
5-
HTMLElementEx,
6-
FreNode,
7-
HookEffect,
8-
} from './type'
1+
import { IFiber, FC, HookEffect, FreNode, Child, FreText } from './type'
92
import { createElement } from './dom'
103
import { resetCursor } from './hook'
114
import { schedule, shouldYield } from './schedule'
@@ -25,7 +18,7 @@ export const enum TAG {
2518
REPLACE = 1 << 7,
2619
}
2720

28-
export const render = (vnode: FreElement, node: Node) => {
21+
export const render = (vnode: IFiber, node: Node) => {
2922
rootFiber = {
3023
node,
3124
props: { children: vnode },
@@ -120,16 +113,19 @@ const updateHost = (fiber: IFiber) => {
120113
reconcileChidren(fiber, fiber.props.children)
121114
}
122115

123-
const simpleVnode = (type: any) =>
124-
isStr(type) ? createText(type as string) : type
116+
const simpleVnode = (type: IFiber | FreText) =>
117+
isStr(type) ? createText(type) : type
125118

126119
const getParentNode = (fiber: IFiber) => {
127120
while ((fiber = fiber.parent)) {
128121
if (!fiber.isComp) return fiber.node
129122
}
130123
}
131124

132-
const reconcileChidren = (fiber: IFiber, children: FreNode) => {
125+
const reconcileChidren = (
126+
fiber: IFiber,
127+
children: IFiber | IFiber[] | null | undefined
128+
) => {
133129
let aCh = fiber.kids || [],
134130
bCh = (fiber.kids = arrayfy(children))
135131
const actions = diff(aCh, bCh)
@@ -150,23 +146,24 @@ const reconcileChidren = (fiber: IFiber, children: FreNode) => {
150146
}
151147
}
152148

153-
function clone(a, b) {
149+
function clone(a: IFiber, b: IFiber) {
154150
b.hooks = a.hooks
155151
b.ref = a.ref
156152
b.node = a.node // 临时修复
157153
b.kids = a.kids
158154
b.old = a
159155
}
160156

161-
export const arrayfy = (arr: unknown) => (!arr ? [] : isArr(arr) ? arr : [arr])
157+
export const arrayfy = <T>(arr: T | T[] | null | undefined) =>
158+
!arr ? [] : isArr(arr) ? arr : [arr]
162159

163160
const side = (effects: HookEffect[]) => {
164161
effects.forEach((e) => e[2] && e[2]())
165162
effects.forEach((e) => (e[2] = e[0]()))
166163
effects.length = 0
167164
}
168165

169-
const diff = function (a, b) {
166+
const diff = function (a: IFiber[], b: IFiber[]) {
170167
var actions = [],
171168
aIdx = {},
172169
bIdx = {},

src/type.ts

+9-24
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,18 @@ export type Ref<T = any> = RefCallback<T> | RefObject<T> | null
1010

1111
export interface Attributes extends Record<string, any> {
1212
key?: Key
13-
children?: FreNode
1413
ref?: Ref
14+
children?: FreNode
1515
}
1616

1717
export interface FC<P extends Attributes = {}> {
18-
(props: P): FreElement<P> | null
18+
(props: P): IFiber | FreText | null | undefined
1919
fiber?: IFiber
2020
type?: string
2121
memo?: boolean
2222
shouldUpdate?: (newProps: P, oldProps: P) => boolean
2323
}
2424

25-
export interface FreElement<P extends Attributes = any, T = string> {
26-
type: T
27-
props: P
28-
key: string
29-
}
30-
3125
export interface Hooks {
3226
list: HookList[]
3327
layout: HookEffect[]
@@ -44,11 +38,11 @@ export type HookReducer<V = any, A = any> = [value: V, dispatch: Dispatch<A>]
4438

4539
export interface IFiber<P extends Attributes = any> {
4640
key?: string
47-
type: string | FC<P>
48-
parentNode: HTMLElementEx | {}
49-
node: HTMLElementEx
50-
kids?: any
51-
dirty: boolean
41+
type?: string | FC<P>
42+
parentNode?: HTMLElementEx | {}
43+
node?: HTMLElementEx
44+
kids?: IFiber[]
45+
dirty?: boolean
5246
parent?: IFiber<P>
5347
sibling?: IFiber<P>
5448
child?: IFiber<P>
@@ -64,23 +58,14 @@ export interface IFiber<P extends Attributes = any> {
6458
export type HTMLElementEx = HTMLElement | Text | SVGElement
6559

6660
export type FreText = string | number
67-
export type FreNode =
68-
| FreText
69-
| FreElement
70-
| FreNode[]
71-
| boolean
72-
| null
73-
| undefined
61+
export type FreNode = Child[] | Child
62+
export type Child = IFiber | FreText | null | undefined | boolean
7463
export type SetStateAction<S> = S | ((prevState: S) => S)
7564
export type Dispatch<A> = (value: A) => void
7665
export type Reducer<S, A> = (prevState: S, action: A) => S
7766
export type EffectCallback = () => any | (() => () => any)
7867
export type DependencyList = ReadonlyArray<unknown>
7968

80-
export interface PropsWithChildren {
81-
children?: FreNode
82-
}
83-
8469
export type ITaskCallback = (() => ITaskCallback) | null
8570

8671
export interface ITask {

0 commit comments

Comments
 (0)