mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-08 00:26:37 +08:00
前端显式 any 类型清理
全前端显式 any 计数 2→0:Slot children?: any → ReactNode | MotionValue 联合(motion 真实类型),顺带修复潜在崩溃(原代码在 isValidElement 前访问 children.type,children 缺失时 TypeError,现无效 children 返回 null,hooks 无条件合规);useControlledState Rest extends any[] → unknown[]。两处 eslint-disable no-explicit-any 注释随之删除。 Experiments: #28 Metric: 全前端 any 2 → 0,tsc/eslint/vitest 全绿
This commit is contained in:
@@ -1,7 +1,12 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { type HTMLMotionProps, isMotionComponent, motion } from 'motion/react';
|
import {
|
||||||
|
type HTMLMotionProps,
|
||||||
|
type MotionValue,
|
||||||
|
isMotionComponent,
|
||||||
|
motion,
|
||||||
|
} from 'motion/react';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
|
||||||
type AnyProps = Record<string, unknown>;
|
type AnyProps = Record<string, unknown>;
|
||||||
@@ -16,8 +21,7 @@ type WithAsChild<Base extends object> =
|
|||||||
| (Base & { asChild?: false | undefined });
|
| (Base & { asChild?: false | undefined });
|
||||||
|
|
||||||
type SlotProps<T extends HTMLElement = HTMLElement> = {
|
type SlotProps<T extends HTMLElement = HTMLElement> = {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
children?: React.ReactNode | MotionValue<string> | MotionValue<number>;
|
||||||
children?: any;
|
|
||||||
} & DOMMotionProps<T>;
|
} & DOMMotionProps<T>;
|
||||||
|
|
||||||
function mergeRefs<T>(
|
function mergeRefs<T>(
|
||||||
@@ -63,21 +67,24 @@ function Slot<T extends HTMLElement = HTMLElement>({
|
|||||||
ref,
|
ref,
|
||||||
...props
|
...props
|
||||||
}: SlotProps<T>) {
|
}: SlotProps<T>) {
|
||||||
|
const isValidChild = React.isValidElement(children);
|
||||||
|
const childrenType = isValidChild ? children.type : undefined;
|
||||||
|
|
||||||
const isAlreadyMotion =
|
const isAlreadyMotion =
|
||||||
typeof children.type === 'object' &&
|
isValidChild &&
|
||||||
children.type !== null &&
|
typeof childrenType === 'object' &&
|
||||||
isMotionComponent(children.type);
|
childrenType !== null &&
|
||||||
|
isMotionComponent(childrenType);
|
||||||
|
|
||||||
const Base = React.useMemo(
|
const Base = React.useMemo(
|
||||||
() =>
|
() =>
|
||||||
isAlreadyMotion
|
isAlreadyMotion
|
||||||
? (children.type as React.ElementType)
|
? (childrenType as React.ElementType)
|
||||||
: motion.create(children.type as React.ElementType),
|
: motion.create(childrenType as React.ElementType),
|
||||||
[isAlreadyMotion, children.type],
|
[isAlreadyMotion, childrenType],
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!React.isValidElement(children)) return null;
|
if (!isValidChild) return null;
|
||||||
|
|
||||||
const { ref: childRef, ...childProps } = children.props as AnyProps;
|
const { ref: childRef, ...childProps } = children.props as AnyProps;
|
||||||
|
|
||||||
const mergedProps = mergeProps(childProps, props);
|
const mergedProps = mergeProps(childProps, props);
|
||||||
|
|||||||
@@ -14,8 +14,7 @@ interface CommonControlledStateProps<T> {
|
|||||||
* const [value, setValue] = useControlledState({ value: propValue, onChange: console.log })
|
* const [value, setValue] = useControlledState({ value: propValue, onChange: console.log })
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
export function useControlledState<T, Rest extends unknown[] = []>(
|
||||||
export function useControlledState<T, Rest extends any[] = []>(
|
|
||||||
props: CommonControlledStateProps<T> & {
|
props: CommonControlledStateProps<T> & {
|
||||||
onChange?: (value: T, ...args: Rest) => void;
|
onChange?: (value: T, ...args: Rest) => void;
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user