You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript:如何仅在其他文件定义类型时导入该类型

在自动生成的Preact类型文件中,根据Web组件是否导出指定类型做条件类型定义

我有一批Web组件文件,部分文件会导出一个可选类型(实际是自定义事件event.detail的类型接口,简称OptionalType)。另外有一批自动生成的文件,每个对应一个Web组件,用来提供该组件的Preact类型。现在需要在这些自动生成的文件里,根据原Web组件文件是否导出OptionalType,来条件定义部分类型。

组件文件示例

部分Web组件文件会包含如下导出:

export interface OptionalType {
  name: string
}

最初尝试的问题

我一开始尝试用import * as all导入整个模块,再通过typeof all判断是否存在OptionalType,写法如下:

import * as all from "./my-component"

type OptionalType = typeof all extends {
  OptionalType: unknown
}
  ? typeof all["OptionalType"]
  : never

// 使用OptionalType

但这种写法不生效——在JavaScript中all是包含所有导出的对象,但在TypeScript里,typeof all得到的是模块的命名空间类型,无法通过这种方式判断导出类型是否存在。不过内联定义测试时逻辑是正常的:

interface All {
  OptionalType: {
    name: string
  }
}

type OptionalTypeInline = All extends {
  OptionalType: unknown
}
  ? All["OptionalType"]
  : never

// 使用OptionalType

正确的实现方式

要正确判断模块是否导出指定类型,应该直接针对模块的导出类型集合做键检查,结合import type来实现:

import type * as all from "./my-component"

type OptionalType = 'OptionalType' extends keyof all 
  ? all['OptionalType'] 
  : never

这种写法直接验证OptionalType是否属于模块导出类型的键,能正确推导对应的类型,不存在时则返回never。

实际场景的最终方案

后来我发现实际场景是处理CustomEvents,通过重构代码解决了问题,最终调整为如下写法:

[K in keyof Events]: (
    e: Events[K] extends keyof all.CustomEvents
        ? TargetedEvent<Component> & { detail: all.CustomEvents[Events[K]] }
        : TargetedEvent<Component>
) => void

内容的提问来源于stack exchange,提问作者Tigran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 06:01:05