lynx-typescript

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

TypeScript @ Lynx

TypeScript @ Lynx

This Skill summarizes common TypeScript issues and their solutions in Lynx development, mainly covering environment configuration, type extending, event handling, components, and ReactLynx advanced usages.
本Skill总结了Lynx开发中常见的TypeScript问题及其解决方案,主要涵盖环境配置、类型扩展、事件处理、组件以及ReactLynx高级用法。

1. Configuration (Environment Configuration)

1. 配置(环境配置)

1.1
tsconfig.json
Configuration

1.1
tsconfig.json
配置

Rspeedy reads the
tsconfig.json
in the root directory by default. Since Rspeedy uses SWC for transpilation, it is recommended to enable the
isolatedModules
option to avoid cross-file type reference errors.
json
{
  "compilerOptions": {
    "isolatedModules": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}
Rspeedy默认读取根目录下的
tsconfig.json
文件。由于Rspeedy使用SWC进行转译,建议启用
isolatedModules
选项以避免跨文件类型引用错误。
json
{
  "compilerOptions": {
    "isolatedModules": true,
    "paths": {
      "@/*": ["./src/*"]
    }
  }
}

1.2 Type Packages Installation

1.2 类型包安装

Ensure the correct type packages are installed. @lynx-js/types is the core type package for Lynx.
  • ReactLynx: Install
    @lynx-js/types
    and
    @lynx-js/react
    .
确保安装了正确的类型包。@lynx-js/types是Lynx的核心类型包。
  • ReactLynx:安装
    @lynx-js/types
    @lynx-js/react

1.3 Type Declaration File
rspeedy-env.d.ts

1.3 类型声明文件
rspeedy-env.d.ts

To allow TypeScript to recognize Rspeedy's built-in features (such as CSS Modules, static resource imports), you need to create a
src/rspeedy-env.d.ts
file in the project:
typescript
/// <reference types="@rspeedy/core/client" />
(Note: The actual package might depend on your Rspeedy setup, typically
@rspeedy/core
or similar for open source)
为了让TypeScript识别Rspeedy的内置特性(如CSS Modules、静态资源导入),你需要在项目中创建
src/rspeedy-env.d.ts
文件:
typescript
/// <reference types="@rspeedy/core/client" />
(注意:实际依赖包可能取决于你的Rspeedy设置,开源版本通常为
@rspeedy/core
或类似包)

1.4 ReactLynx JSX Configuration

1.4 ReactLynx JSX 配置

For ReactLynx projects, you need to configure
jsxImportSource
as
@lynx-js/react
in
tsconfig.json
to ensure JSX is compiled correctly and gets type support.
json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "@lynx-js/react"
  }
}
对于ReactLynx项目,你需要在
tsconfig.json
中将
jsxImportSource
配置为
@lynx-js/react
,以确保JSX被正确编译并获得类型支持。
json
{
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "@lynx-js/react"
  }
}

2. Extending Lynx Types

2. 扩展Lynx类型

Lynx provides default type definitions, but you usually need to extend them to suit business needs.
Lynx提供了默认的类型定义,但通常你需要扩展它们以适配业务需求。

2.1 GlobalProps

2.1 GlobalProps

Extend the type of
lynx.__globalProps
:
typescript
declare module '@lynx-js/types' {
  interface GlobalProps {
    appTheme: string;
    title: string;
    // Add other custom global properties
  }
}
export {};
This way, there will be type hints when using
lynx.__globalProps.appTheme
.
扩展
lynx.__globalProps
的类型:
typescript
declare module '@lynx-js/types' {
  interface GlobalProps {
    appTheme: string;
    title: string;
    // 添加其他自定义全局属性
  }
}
export {};
这样,在使用
lynx.__globalProps.appTheme
时就会有类型提示。

2.2 InitData

2.2 InitData

Extend the return value type of the ReactLynx Hook
useInitData()
:
typescript
declare module '@lynx-js/react' {
  interface InitData {
    userInfo: {
      name: string;
      id: number;
    };
    // Add other initialization data properties
  }
}
export {};
This way, there will be type hints when using
useInitData().userInfo
.
扩展ReactLynx Hook
useInitData()
的返回值类型:
typescript
declare module '@lynx-js/react' {
  interface InitData {
    userInfo: {
      name: string;
      id: number;
    };
    // 添加其他初始化数据属性
  }
}
export {};
这样,在使用
useInitData().userInfo
时就会有类型提示。

2.3 IntrinsicElements (Custom Native Components)

2.3 IntrinsicElements(自定义原生组件)

If custom native components are used, you need to extend
IntrinsicElements
to get JSX type checking:
typescript
import type * as Lynx from '@lynx-js/types';
import type { CSSProperties } from '@lynx-js/types';

declare module '@lynx-js/types' {
  interface IntrinsicElements extends Lynx.IntrinsicElements {
    'custom-input': {
      'bindcustom-event'?: (e: { type: 'custom-event'; detail: { value: string } }) => void;
      value?: string;
      class?: string;
      className?: string;
      style?: string | CSSProperties;
    };
  }
}
如果使用了自定义原生组件,你需要扩展
IntrinsicElements
以获得JSX类型检查:
typescript
import type * as Lynx from '@lynx-js/types';
import type { CSSProperties } from '@lynx-js/types';

declare module '@lynx-js/types' {
  interface IntrinsicElements extends Lynx.IntrinsicElements {
    'custom-input': {
      'bindcustom-event'?: (e: { type: 'custom-event'; detail: { value: string } }) => void;
      value?: string;
      class?: string;
      className?: string;
      style?: string | CSSProperties;
    };
  }
}

2.4 NativeModules

2.4 NativeModules

Extend the
NativeModules
type to support custom Native Module calls:
typescript
declare module '@lynx-js/types' {
  interface NativeModules {
    NativeLocalStorageModule: {
      getStorageItem(key: string): string | null;
      setStorageItem(key: string, value: string): void;
    };
  }
}
export {};
扩展
NativeModules
类型以支持自定义Native Module调用:
typescript
declare module '@lynx-js/types' {
  interface NativeModules {
    NativeLocalStorageModule: {
      getStorageItem(key: string): string | null;
      setStorageItem(key: string, value: string): void;
    };
  }
}
export {};

2.5 Lynx Global Object

2.5 Lynx全局对象

Extend the type of the
lynx
global object (e.g., adding a custom method
lynx.myMethod
):
typescript
declare module '@lynx-js/types' {
  interface Lynx {
    myMethod(param: string): void;
    customProperty: number;
  }
}
export {};
This way, there will be type hints when using
lynx.myMethod('test')
.
扩展
lynx
全局对象的类型(例如添加自定义方法
lynx.myMethod
):
typescript
declare module '@lynx-js/types' {
  interface Lynx {
    myMethod(param: string): void;
    customProperty: number;
  }
}
export {};
这样,在使用
lynx.myMethod('test')
时就会有类型提示。

3. Event Handling

3. 事件处理

When handling events, you should avoid using the
any
type. Lynx provides standard event types.
处理事件时应避免使用
any
类型。Lynx提供了标准的事件类型。

3.1 Basic Events and Touch Events

3.1 基础事件与触摸事件

For touch events (like
bindtap
,
bindtouchstart
), the event object contains properties like
detail
,
touches
,
changedTouches
.
typescript
// Example: Handling a tap event
const handleTap = (event: any) => { // Using any is not recommended
  console.log(event);
};

// Recommended approach: Define event interfaces or use inferred types
import type { TouchEvent } from '@lynx-js/types';

// Usage example
const handleButtonTap = (e: TouchEvent) => {
  const { dataset } = e.currentTarget;
  console.log('Tapped!', dataset);
};
对于触摸事件(如
bindtap
bindtouchstart
),事件对象包含
detail
touches
changedTouches
等属性。
typescript
// 示例:处理点击事件
const handleTap = (event: any) => { // 不推荐使用any
  console.log(event);
};

// 推荐方式:定义事件接口或使用推断类型
import type { TouchEvent } from '@lynx-js/types';

// 使用示例
const handleButtonTap = (e: TouchEvent) => {
  const { dataset } = e.currentTarget;
  console.log('已点击!', dataset);
};

4. ReactLynx & LynxUI Types

4. ReactLynx & LynxUI 类型

4.1 LynxUI Component Types

4.1 LynxUI组件类型

LynxUI components usually export the type definitions for their Props and Ref. When using components from
@lynx-js/lynx-ui
(or its sub-packages like
@lynx-js/lynx-ui-button
,
@lynx-js/lynx-ui-scroll-view
, etc.), you should use these exported types.
Best Practices:
  1. Explicitly import Props and Ref types.
  2. Specify the Ref type when using
    useRef
    .
typescript
import { ScrollView } from '@lynx-js/lynx-ui-scroll-view';
import type { ScrollViewRef, ScrollViewProps } from '@lynx-js/lynx-ui-scroll-view';
import { useRef } from '@lynx-js/react';

function App() {
  // Explicitly specify the Ref type
  const scrollViewRef = useRef<ScrollViewRef>(null);

  const handleScroll: ScrollViewProps['onScroll'] = (e) => {
    console.log('Scrolled:', e.detail);
  };

  return (
    <ScrollView
      ref={scrollViewRef}
      onScroll={handleScroll}
      // ...
    />
  );
}
LynxUI组件通常会导出其Props和Ref的类型定义。使用
@lynx-js/lynx-ui
(或其子包如
@lynx-js/lynx-ui-button
@lynx-js/lynx-ui-scroll-view
等)中的组件时,应使用这些导出的类型。
最佳实践:
  1. 显式导入Props和Ref类型。
  2. 使用
    useRef
    时指定Ref类型。
typescript
import { ScrollView } from '@lynx-js/lynx-ui-scroll-view';
import type { ScrollViewRef, ScrollViewProps } from '@lynx-js/lynx-ui-scroll-view';
import { useRef } from '@lynx-js/react';

function App() {
  // 显式指定Ref类型
  const scrollViewRef = useRef<ScrollViewRef>(null);

  const handleScroll: ScrollViewProps['onScroll'] = (e) => {
    console.log('已滚动:', e.detail);
  };

  return (
    <ScrollView
      ref={scrollViewRef}
      onScroll={handleScroll}
      // ...
    />
  );
}

4.2 MainThreadRef and Multi-threading APIs

4.2 MainThreadRef与多线程API

ReactLynx provides dedicated APIs for handling main thread state.
typescript
import { useMainThreadRef, runOnMainThread } from '@lynx-js/react';

function AnimationComponent() {
  // Define the data type stored in MainThreadRef
  const widthRef = useMainThreadRef<number>(0);

  const handleTap = () => {
    // Call main thread logic from the background thread
    runOnMainThread(widthRef, (ref) => {
      // This callback executes on the main thread
      ref.current += 10;
      console.log('New width:', ref.current);
    });
  };

  return <view bindtap={handleTap} />;
}
ReactLynx提供了用于处理主线程状态的专用API。
typescript
import { useMainThreadRef, runOnMainThread } from '@lynx-js/react';

function AnimationComponent() {
  // 定义存储在MainThreadRef中的数据类型
  const widthRef = useMainThreadRef<number>(0);

  const handleTap = () => {
    // 从后台线程调用主线程逻辑
    runOnMainThread(widthRef, (ref) => {
      // 此回调在主线程执行
      ref.current += 10;
      console.log('新宽度:', ref.current);
    });
  };

  return <view bindtap={handleTap} />;
}

4.3 Lynx Global Object

4.3 Lynx全局对象

The
lynx
global object provides methods like
querySelector
.
typescript
// Select element
const element = lynx.querySelector('#my-id');
// The type of element is Element | null

// Register data processors (functional)
lynx.registerDataProcessors({
  defaultDataProcessor: (data) => {
    return data;
  }
});
lynx
全局对象提供了
querySelector
等方法。
typescript
// 选择元素
const element = lynx.querySelector('#my-id');
// element的类型为Element | null

// 注册数据处理器(函数式)
lynx.registerDataProcessors({
  defaultDataProcessor: (data) => {
    return data;
  }
});

5. Common Error Fix Guide

5. 常见错误修复指南

  • Error: Property '...' does not exist on type 'GlobalProps' -> Refer to 2.1 GlobalProps for type extension.
  • Error: Property '...' does not exist on type 'InitData' -> Refer to 2.2 InitData for type extension.
  • Error: Property '...' does not exist on type 'JSX.IntrinsicElements' -> Refer to 2.3 IntrinsicElements (Custom Native Components) for type extension. -> Also check if conflicting type packages are installed.
  • Error: Property 'cancelAnimationFrame' does not exist on type 'UnsafeLynx' or CSSProperties not assignable -> Cause: Usually caused by installing multiple conflicting Lynx type packages. -> Solution: Check
    package.json
    , remove unnecessary type packages, ensuring only
    @lynx-js/types
    along with
    @lynx-js/react
    are kept.
  • Error: Cannot find module '...' or its corresponding type declarations -> Check if
    paths
    is configured (refer to 1.1) or if
    d.ts
    definitions are missing.
  • Error: 'lynx' is not defined -> Ensure the project contains the reference
    import {} from "@lynx-js/react"
    .
  • When using
    declare module '@lynx-js/types'
    in a
    d.ts
    file, make sure to export an empty object
    export {}
    to avoid global pollution.
  • 错误:Property '...' does not exist on type 'GlobalProps' -> 参考2.1 GlobalProps进行类型扩展。
  • 错误:Property '...' does not exist on type 'InitData' -> 参考2.2 InitData进行类型扩展。
  • 错误:Property '...' does not exist on type 'JSX.IntrinsicElements' -> 参考2.3 IntrinsicElements(自定义原生组件)进行类型扩展。 -> 同时检查是否安装了冲突的类型包。
  • 错误:Property 'cancelAnimationFrame' does not exist on type 'UnsafeLynx'CSSProperties not assignable -> 原因:通常是由于安装了多个冲突的Lynx类型包导致。 -> 解决方案:检查
    package.json
    ,移除不必要的类型包,确保只保留
    @lynx-js/types
    @lynx-js/react
  • 错误:Cannot find module '...' or its corresponding type declarations -> 检查是否配置了
    paths
    (参考1.1)或是否缺少
    d.ts
    定义。
  • 错误:'lynx' is not defined -> 确保项目中包含引用
    import {} from "@lynx-js/react"
  • d.ts
    文件中使用
    declare module '@lynx-js/types'
    时,确保导出空对象
    export {}
    以避免全局污染。