Skip to content
This repository was archived by the owner on May 31, 2026. It is now read-only.

refactor: enable strict TypeScript and add CI#2

Merged
lc-soft merged 5 commits into
developfrom
copilot/fix-typescript-type-errors
May 30, 2026
Merged

refactor: enable strict TypeScript and add CI#2
lc-soft merged 5 commits into
developfrom
copilot/fix-typescript-type-errors

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 29, 2026

This PR enables strict TypeScript checking and resolves the resulting type failures across binding, compile, hook, widget, and JSX runtime layers. The changes focus on removing unsafe inference (never, implicit any, undefined paths) while preserving current runtime behavior.

  • tsconfig strictness

    • Enabled compilerOptions.strict and addressed all surfaced errors without widening to any as a fallback pattern.
    • Added explicit rootDir for stable declaration/build layout under current TypeScript behavior.
  • Binding/runtime core (src/binding.ts)

    • Fixed popFunctionComponent to actually pop context state.
    • Typed typeNameMap as Partial<Record<CType, string>> to allow safe enum indexing.
    • Removed compiler self-reference inside compileFunction in favor of local function calls.
    • Improved createBinding/createObjectBinding generics so proxy-backed metadata + attached data preserve shape under strict mode.
    • Made apply trap return explicit undefined to match the intended Value | void behavior path.
  • React tree compilation (src/compile.ts)

    • Fixed dynamic attribute mapping by typing attrMap as Record<string, string>.
    • Added explicit child unions in transformNodeChildren to avoid never[].
    • Made transformReactNode explicitly return Node | undefined and filtered undefined before assigning to Node[].
    • Introduced typed props access (Record<string, any) where dynamic key access is required.
    • Refactored compile element selection to an IIFE so el is always initialized under strict analysis.
    • Defined Node shape explicitly with children: Node[].
  • State/ref hooks

    • src/useState.ts
      • Guarded isNumericType with valueType !== undefined.
      • Added explicit error path for invalid numeric CType to eliminate unassigned control-flow branches.
    • src/useRef.ts
      • Removed as unknown as double assertion by returning a typed intersection (ObjectBinding & WidgetRefBinding).
      • Narrowed WidgetInstance.value setter input type to string | ObjectBinding.
      • Added explicit getter/setter typing for strict compatibility.
      • Fixed generated call string in setTextInputValue() and added explicit return typing for getTextInputValue().
  • Widget components (src/widgets.tsx)

    • Renamed the component meta type to FunctionWidget for clearer semantics.
    • Refactored widget exports to const + arrow function style with typed declarations.
    • Added reusable helpers to reduce repetitive simple tag-mapping components while keeping shouldPreRender behavior.
  • JSX runtime typing (src/jsx-runtime.ts)

    • Aligned JSX factory signature with React key typing (key?: React.Key).
    • Removed module augmentation override of react/jsx-runtime exports to avoid declaration conflicts with @types/react.
  • Build/test and CI

    • Added scripts: build, typecheck, and test:unit; updated test to run unit tests.
    • Added automated unit tests for widget tag mapping, metadata (shouldPreRender), and RouterLink prop mapping.
    • Added GitHub Actions workflow to run install, typecheck, and tests on PRs/pushes (with explicit minimal token permissions).
const attrMap: Record<string, string> = { className: "class", $ref: "ref" };

node.children = children
  .map(transformReactNode)
  .filter((n): n is Node => n !== undefined);
Original prompt

修复 TypeScript 类型错误、补充缺失类型声明、纠正属性类型被推断为 never 的问题

请按照以下实施计划,对项目中的所有 TypeScript 类型错误进行修复。


一、tsconfig.json — 启用严格检查

compilerOptions 中添加 "strict": true,然后修复因此暴露出来的所有错误。


二、src/binding.ts

2.1 apply trap 返回类型不符

createBindingProxyapply trap 没有 return 语句(返回 undefined),与 BindingBase 接口声明的 (...arg: Value[]): Value 返回类型不符。
修复:将 apply trap 的返回类型改为 Value | void,或在函数调用结束后 return undefined

2.2 popFunctionComponent 逻辑 bug

popFunctionComponent 内部错误地调用了 contextList.push(ctx) 而不是 contextList.pop()
修复:改为 contextList.pop(),并移除多余的 ctx 参数(因为 pop 不需要参数)。

2.3 typeNameMap 索引类型错误

typeNameMap 的 key 是字面量联合类型,但用 CType(包含所有枚举值)去索引会导致类型错误。
修复

const typeNameMap: Partial<Record<CType, string>> = {
  [CType.Double]: "double",
  [CType.Size]: "size_t",
  [CType.Int]: "int",
  [CType.String]: "char*",
};

2.4 compileFunction 中自引用 compiler 对象

compileFunction 内部调用 compiler.compileVariableDeclarationcompiler.compileObjectDestroyer,而 compiler 在文件末尾定义,存在循环引用和类型推断问题。
修复:将这两处改为直接调用本地函数 compileVariableDeclaration(item)compileObjectDestroyer(item.initializer)

2.5 createBinding 参数 data 类型

data: Record<string, any> = {} 导致 Proxy target 的属性类型推断丢失。
修复:改为更具体的类型,或为泛型添加约束。


三、src/compile.ts

3.1 attrMap 索引导致 key 被推断为 never

const attrMap = { className: "class", $ref: "ref" };
if (key in attrMap) {
  key = attrMap[key]; // TS 报错:key 被推断为 never
}

修复

const attrMap: Record<string, string> = { className: "class", $ref: "ref" };

3.2 children 数组类型被推断为 never[]

transformNodeChildrenconst children = [] 因多种类型 push 而被推断为 never[]
修复

const children: (string | Value | ReactElement)[] = [];

3.3 transformReactNode 返回 Node | undefined,但赋值给 Node[]

函数多处隐式返回 undefined,赋值给 node.children 时报类型错误。
修复:声明返回类型为 Node | undefined,在赋值时过滤 undefined:

node.children = children.map(...).filter((n): n is Node => n !== undefined);

同时将 Node 类型的 children 字段声明为 Node[](通过修改 createNode 函数的返回类型)。

3.4 el.props 类型过于宽泛导致属性访问报错

严格模式下 ReactElementprops 默认类型为 {},动态访问属性会报错。
修复:在需要动态访问 props 的地方断言为 Record<string, any>

const props = el.props as Record<string, any>;

3.5 compile 函数中 let el: ReactElement 可能未初始化

严格模式下 TS 检测到 elswitch 语句后可能未赋值。
修复:使用立即执行函数(IIFE)或初始赋值确保 el 总是有值。


四、src/useState.ts

4.1 switch-case 穿透导致 value 可能未赋值

number 分支在 isNumericType(valueType) 为 false 时 fall-through 到 default,但 TS 无法保证 value 在所有路径都被赋值。
修复:为 number 分支的 isNumericType 判断失败情况明确添加 throwbreak

4.2 isNumericType(valueType) 参数可能为 undefined

valueType?: CType 是可选参数,类型为 CType | undefined,但 isNumericType 接受 CType,不接受 undefined
修复

if (valueType !== undefined && isNumericType(valueType)) { ... }

五、src/useRef.ts

5.1 移除 as unknown as 双重类型断言

useRef 返回值通过 as unknown as { name: string; current: WidgetInstance } 强转,绕过类型检查。
修复:定义明确的返回类型接口,修正 createObjectBinding 调用的数据结构,使返回类型自然匹配,避免双重断言。

5.2 WidgetInstance.value setter 参数类型

setter 参数为 any,getter 返回 ObjectBinding,在严格模式下需要显式标注。
修复:将 setter 参数类型改为 string | ObjectBinding 或其他更具体的类型。


六、src/widgets.tsx

6.1 函数组件上挂载 shouldPreRender 属性类型缺失

Widget.shouldPreRender = true; // TS 报错:Property 'shouldPreRender' does not exist

修复:定义包含 shouldPreRender 属性的函数类型,或使用 Object.assign

// 方案一:扩展函数类型
type WidgetComponent<T = WidgetProps> = ((props: T) => React.ReactElement) & {
  shouldPreRender?: boolean;
};
// 方案二:使用 Object.assign 语法
export const Widget = Object.assign(
  (props: WidgetProps) => <widget {...props} />,
  { shouldPreRender: true }
);

对所有组件(Widget、Button、Link、Text、TextInput、ScrollArea、ScrollAreaContent、Scrollbar、RouterLink、RouterView)统一处理。


七、src/jsx-runtime.ts

7.1 自定义 JSXFactor 类型与 @types/reactjsx-runtime 官方类型对齐

检查 @types/reactreact/jsx-runtime 的官方 jsx / jsxs 类型签名,确保自定义 JSXFactor 与之兼容,避免模块声明覆盖引发的类型冲突。


执行顺序

  1. 修复 binding.ts(基础类型,其他文件依赖)
  2. 修复 compile.ts(最多类型错误)
  3. 修复 useState.ts
  4. 修复 useRef.ts
  5. 修复 widgets.tsx
  6. 修复 jsx-runtime.ts
  7. 最后更新 tsconfig.json 开启 strict: true 并验证无剩余错误

请确保修改后项目可以通过 tsc --noEmit 编译无错误。

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: 我想解决这个项目内的 ts 类型错误,补充缺失的类型声明,纠正部分属性类型被推断成 never 的问题。你帮我写一份实施计划吧?

Assistant: 以下是针对 lcui-dev/react 项目的 TypeScript 类型错误修复实施计划,按问题严重程度和模块组织:


实施计划:修复 TypeScript 类型错误

一、tsconfig.json — 启用严格检查

问题:当前未开启 strict,导致大量隐式类型问题被掩盖。
操作:在 compilerOptions 中添加 "strict": true,然后逐步修复暴露出来的错误(可分步骤启用 noImplicitAnystrictNullChecks 等)。


二、src/binding.ts

2.1 BindingBase 函数签名返回类...

This pull request was created from Copilot chat.

Copilot AI changed the title [WIP] Fix TypeScript type errors and improve type declarations Enable strict TypeScript mode and resolve core typing/runtime-shape mismatches May 29, 2026
Copilot AI requested a review from lc-soft May 29, 2026 02:49
@lc-soft
Copy link
Copy Markdown
Member

lc-soft commented May 29, 2026

@copilot 补充 GitHub Actions 配置和测试用例。

Copy link
Copy Markdown
Member

@lc-soft lc-soft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot 按评审意见做修改。

Comment thread src/widgets.tsx Outdated
Comment thread src/widgets.tsx Outdated
Copy link
Copy Markdown
Contributor Author

Copilot AI commented May 29, 2026

@copilot 补充 GitHub Actions 配置和测试用例。

已补充 GitHub Actions 配置和测试用例,见提交 1fff519

@copilot 按评审意见做修改。

已按评审意见完成修改(包括 widgets 命名与封装重构),见提交 1fff519

Copilot AI changed the title Enable strict TypeScript mode and resolve core typing/runtime-shape mismatches Enable strict TypeScript mode, add CI/test coverage, and refine widget component typing May 29, 2026
Copilot AI requested a review from lc-soft May 29, 2026 07:10
Copy link
Copy Markdown
Member

@lc-soft lc-soft left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot 按照审核意见做修改。

Comment thread src/widgets.tsx Outdated
Copilot AI requested a review from lc-soft May 29, 2026 07:27
@lc-soft
Copy link
Copy Markdown
Member

lc-soft commented May 29, 2026

@copilot 按照 Angular 规范调整 PR 标题,长度不超过 72 字符。

@lc-soft lc-soft marked this pull request as ready for review May 29, 2026 11:20
- Drop package-lock.json; switch to Yarn 4 (Berry) via Corepack

- Add packageManager field and .yarnrc.yml (nodeLinker: node-modules)

- Update .gitignore for Yarn Berry layout

- Replace npm run with yarn in package.json scripts

- Update CI workflow to use corepack enable + yarn install --immutable
@lc-soft lc-soft changed the title Enable strict TypeScript mode, add CI/test coverage, and refine widget component typing refactor: enable strict TypeScript and add CI May 30, 2026
@lc-soft lc-soft merged commit a4ab974 into develop May 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants