CloudFog API Gateway

Limited Time

200+ AI Models Integration Hub

Claim Offer Now
Resolvedtypescript

TypeScript 类型检查求助:如何防止默认参数绕过泛型约束?🤔

开发者小明

1/8/2025

92 views1 likes

嘿,大家好!👋

最近我在折腾 TypeScript 的时候遇到了一个让我抓狂的问题。😵‍💫 我想创建一个 Example 类,类型是 Example<{ min: 1 }>。一切看起来都很顺利,直到我发现默认参数居然绕过了泛型类型检查!这让我有点崩溃。😩

代码片段

type Config = { min?: number; max?: number; }; class Example<C extends Config> { example = true; constructor(private config: Readonly<C> = {} as C) {} public min<const N extends number>(min: N) { return new Example<C & { min: N }>({ ...this.config, min, }); } }

目标

我想创建一个 Example 类,类型是 Example<{ min: 1 }>

测试

我写了一个 test 函数来测试各种构造类的方法:

const test = (example: Example<{ min: 1 }>) => example;

结果

以下这些都能正常工作:

test(new Example({ min: 1 })); test(new Example().min(1)); test(new Example({}).min(1));

但是,以下这些不应该工作:

test(new Example({})); test(new Example({ min: 2 })); test(new Example().min(2));

这些都如预期地失败了。👍

问题

然而,当我用默认参数测试时:

test(new Example());

居然没有报错!😱 默认的 {} 不应该能赋值给 { min: 1 } 啊!

尝试过的解决方案

我试着修改 test 函数:

const test = <C extends { min: 1 }>(example: Example<C>) => example;

这样确实报错了,但这不是我想要的解决方案。😅

问题所在

我希望 new Example() 不能被赋值给 Example<{ min: 1 }>。这段代码:

const example: Example<{ min: 1 }> = new Example();

应该抛出一个错误才对。

求助

有没有大佬能帮我看看这个问题怎么解决?🙏 我已经被这个问题折腾得快疯了,真心求指点!

PS: 我在 TypeScript Playground 上也试过了,还是不行。😔

标签: typescript, generics, 类型检查

谢谢大家!❤️

1 Answers

架构师老张

1/8/2025

Best Answer13

Answer #1 - Best Answer

嘿,你好啊!👋

我太理解你遇到的这个 TypeScript 类型检查问题了。😅 我之前也在泛型和默认参数上栽过跟头,真是让人头疼。不过别担心,我们一起来解决这个问题吧!

问题分析

你希望 new Example() 不能被赋值给 Example<{ min: 1 }>,但由于默认参数的存在,TypeScript 允许 {} 作为默认值,这就绕过了类型检查。我们需要确保在没有提供参数的情况下,类型约束依然有效。

解决方案

一种方法是通过在构造函数中引入类型检查来确保默认参数符合预期的类型。我们可以使用类型断言来强制类型检查。以下是一个可能的解决方案:

type Config = { min?: number; max?: number; }; class Example<C extends Config> { example = true; constructor(private config: Readonly<C> = {} as C) { // 添加类型检查 if (config.min === undefined) { throw new Error("Config must have a 'min' property"); } } public min<const N extends number>(min: N) { return new Example<C & { min: N }>({ ...this.config, min, }); } }

解释

  • 类型断言:在构造函数中,我们检查 config.min 是否为 undefined,如果是,就抛出一个错误。这确保了即使使用默认参数,min 也必须被定义。
  • 类型安全:这样一来,new Example() 将抛出错误,因为它不符合 { min: 1 } 的约束。

个人经验提示

  • 常见错误:在使用泛型时,默认参数可能会导致类型检查失效。确保在构造函数中进行必要的检查。
  • 调试技巧:使用 TypeScript 的 strict 模式可以帮助你捕获更多类型错误。

鼓励

希望这个解决方案对你有帮助!如果还有其他问题或者需要进一步的帮助,随时可以找我哦。继续加油,TypeScript 的类型系统虽然复杂,但掌握之后会让你的代码更加健壮!💪

如果有其他问题,欢迎随时提问!😊

CloudFog API Gateway 🔥 New User Special

💥 New User Offer: Get $1 Credit for ¥0.5

Claim Offer Now