以下是代码,关于 naive-ui
可以删除, Record<string, { default: GlobalThemeOverrides } | unknown>
替换为 any
import type { GlobalThemeOverrides } from 'naive-ui'
// 根据 themes 文件夹内的输出结合 import.meta.glob 推断类型是 Record<string, { default: GlobalThemeOverrides }>
const modules = import.meta.glob('./themes/*.ts', { eager: true })
function formatImports(
modules: Record<string, { default: GlobalThemeOverrides } | unknown>,
result: ObjectAny
) {
Object.keys(modules).forEach((key) => {
const defaultModule = (modules[key] as ObjectAny).default
if (!defaultModule) return
const name = key.split('/').pop()?.replace('.ts', '')
result[name as string] = defaultModule
})
return result
}
// themes result
// result: { gray: {}, slate: {} }
// 需要进行类型生成
// type ThemeName = 'gray' | 'slate'
export const themes = formatImports(modules, {})
export const themeNames = Object.keys(themes)
export type ThemeName = (typeof themeNames)[number]
// type UnionOfArrayElements<T extends readonly string[]> = T[number]
// export type ThemeName = UnionOfArrayElements<typeof themeNames>
// 使用过以下方法进行类型推断,但都不能正确的推断字面量类型,似乎字面量类型推断只能是定义的数据而非生成的数据
// 如果你遇到了这个问题并且有解决办法,请求你能够像我分享相关解决办法,非常感谢!
//
// 1. as const
// export const themeNames = Object.keys(themes) as const
// export type ThemeName = (typeof themeNames)[number]
//
// 该方法会出现 TS 错误,因为 as const 不能被这样使用
// Error: 'const' 断言只能作用于枚举成员、字符串、数字、布尔值、数组或对象字面量。
//
// =========================================================================
//
// 2. 辅助类型推断
// type UnionOfArrayElements<T extends readonly string[]> = T[number]
// export type ThemeName = UnionOfArrayElements<(typeof themes)[keyof typeof themes]>
//
// 最终推断出来的是 'gray' 的类型(string),而不是将 'gray' 当成类型
ts 不负责运行时,你的 modules 只有运行之后才知道有什么文件