---
title: 常见问题
summary: 多设备管理常见问题，说明 useDevices 等 Hooks 的 TypeScript 类型推导方案，帮助按设备 key 绑定 Schema 并获得完整 DP 类型提示。
---

# 常见问题

## TypeScript 类型推导：如何让 useDevices / useDevicesProps 等获得完整 DP 类型？

`useDevices`、`useDevicesProps`、`useDevicesActions`、`useStructuredDevicesProps`、`useStructuredDevicesActions` 等多设备 Hooks 默认返回泛型类型，无法推导各设备 key 对应的具体 DP。推荐在项目的 `typings/sdm.d.ts` 中通过 `declare module` 覆写返回类型，实现 **按设备 key 精确绑定 Schema**。

### 第一步：为每种设备定义独立 Schema

在 `src/devices/schema.ts` 中，按设备 PID（角色）分别导出 Schema：

```typescript
// src/devices/schema.ts

/** 主设备 Schema */
export const mainDeviceSchema = [ /* 主设备实际 DPs */ ] as const;

/** lamp1 设备 Schema (PID: xxx) */
export const lampSchema = [ /* 灯具实际 DPs */ ] as const;
```

### 第二步：在 typings/sdm.d.ts 中覆写多设备 Hooks 类型

以 `useDevices` 为例，覆写返回的 `MultiDevicesData`；`useDevicesProps`、`useDevicesActions` 等会基于同一设备映射类型获得推导：

```typescript
// typings/sdm.d.ts
export type LampSchema = typeof import('@/devices/schema').lampSchema;
type LampDevice = import('@ray-js/panel-sdk').SmartDeviceModel<LampSchema>;

declare module '@ray-js/panel-sdk' {
  export type LampInstanceData = {
    devInfo: ReturnType<LampDevice['getDevInfo']>;
    dpSchema: ReturnType<LampDevice['getDpSchema']>;
    network: ReturnType<LampDevice['getNetwork']>;
    bluetooth: ReturnType<LampDevice['getBluetooth']>;
  };

  // 按项目实际设备 key 定义映射
  export type MultiDevicesData = {
    main?: SmartDeviceInstanceData;
    lamp1?: LampInstanceData;
    lamp2?: LampInstanceData;
  };
  export function useDevices(): MultiDevicesData;
  export function useDevices<V>(
    selector: (devicesData: MultiDevicesData) => V,
    equalityFn?: (a: V, b: V) => boolean
  ): V;
}
```

覆写后，所有多设备 Hooks 调用侧无需改动即可获得完整 DP 推导，例如：

```tsx | pure
const devicesData = useDevices();
devicesData.lamp1?.dpSchema.switch_led;   // ✓

const props = useDevicesProps(p => p);
props.lamp1?.switch_led;                   // ✓
```

### 个别页面设备类型不同时：局部类型收窄

若某个页面中特定 key 绑定了不同 Schema 的设备，可在该页面局部定义类型并通过 `as` 收窄，不影响其他页面：

```tsx | pure
import type { SmartDeviceInstanceData, LampInstanceData } from '@ray-js/panel-sdk';
import type { OtherLampInstanceData } from './types';

type MyPageDevicesData = {
  main?: SmartDeviceInstanceData;
  lamp1?: LampInstanceData;
  lamp2?: OtherLampInstanceData;
};

const devicesData = useDevices() as MyPageDevicesData;
```
