TypeScript联合类型中如何实现正确的类型推断?
问题分析与修复方案
问题根源
当你用(() => IConfig) | IConfig作为参数类型时,TypeScript的类型推断逻辑会出现模糊性。因为联合类型包含了函数分支,TS会认为你传入的对象字面量有可能是误写的函数(比如本该写() => ({ ... })却漏了箭头),所以不会严格按照IConfig的规则做校验和提示,反而放宽了限制——这就导致vite: true时没有预期的类型提示,同时不该出现的plugins数组也没触发错误提醒。
修复方案
不要用联合类型,改用函数重载明确区分两种参数场景,让TypeScript能针对每种情况做精准的类型推断:
interface IViteConfig { vite?: true; } interface IWebpackConfig { vite?: false; plugins: string[]; } type IConfig = IViteConfig | IWebpackConfig; // 定义函数重载:明确两种参数形式 function defineConfig(config: IConfig): IConfig; function defineConfig(config: () => IConfig): () => IConfig; // 函数实现逻辑 function defineConfig(config: IConfig | (() => IConfig)) { return config; } // 场景1:直接传配置对象,会触发正确的类型校验和提示 defineConfig({ vite: true, // 正常显示类型提示 // plugins: [], // 这里会触发预期的错误提示(Vite配置不允许plugins) }); defineConfig({ vite: false, plugins: ['webpack-plugin'], // 正常提示plugins的类型要求 }); // 场景2:传返回配置的函数,返回值同样会被严格校验 defineConfig(() => ({ vite: true, // plugins: [], // 此处也会触发错误提示 }));
函数重载让TS清晰识别两种参数模式:传入对象时必须符合IConfig规则,传入函数时必须返回IConfig类型,彻底解决了联合类型带来的推断模糊问题,两种场景下都能得到预期的类型提示和错误校验。
内容的提问来源于stack exchange,提问作者王玉略
相关产品推荐
相关产品推荐

