/* eslint-disable @typescript-eslint/no-explicit-any */ import type { FC } from '../jsx'; import { type AnyFn, isObject } from '../util'; import { REFS } from './common'; import type { ComponentHost } from './component'; export const REF = Symbol('REF'); export interface Ref> { value?: T; } export type RefValue | undefined> = T extends Ref ? R : never; export function ref(): T extends Node ? Ref : T extends FC ? Ref[0]['ref']>> : never { return { [REF]: true, value: undefined } as any; } export function isRef>(v: object): v is Ref { return (v as unknown as { [REF]: boolean })[REF] === true; } export type RefFn = (el: T) => void; /** 用于给编译器使用的 set ref 函数 */ export function setRefForComponent( target: ComponentHost, ref: Ref | RefFn, el: ComponentHost | Node, ) { let rns = target[REFS]; if (!rns) { target[REFS] = rns = []; } rns.push(ref); if (isObject>(ref)) { (ref as Ref).value = el; } else { (ref as RefFn)(el); } }