CloudFog API Gateway

Limited Time

200+ AI Models Integration Hub

Claim Offer Now
Resolvedtypescript

TypeScript 泛型问题:如何防止 `new Example()` 赋值给 `Example<{ min: 1 }>`?🤔

全栈Tom

1/8/2025

95 views8 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, }); } }

我写了个测试函数来验证各种构造类的方式:

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 },这不科学啊!我还试着改了测试函数:

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

这样确实报错了,但这不是我想要的解决方案。问题是 new Example() 不应该能赋值给 Example<{ min: 1 }>

我试了各种方法,还是没搞定。有没有大佬能帮我看看这个问题?🙏

PS: 我在 TypeScript Playground 上也试过了,结果还是一样。链接在这:Playground

谢谢大家!🙌

1 Answers

程序员小王

1/8/2025

Best Answer6

Answer #1 - Best Answer

嘿,你好啊!👋 我太理解你遇到的 TypeScript 泛型问题了 - 我之前也栽在这上面!TypeScript 的类型系统有时候会让人抓狂,特别是当你想要严格控制类型时。别担心,我们一起来看看怎么解决这个问题。

问题分析

你遇到的问题是因为 TypeScript 的类型推断机制。默认情况下,new Example() 会被推断为 Example<{}>,而 {} 是可以赋值给任何对象类型的,包括 { min: 1 }。这就是为什么 test(new Example()) 没有报错。

解决方案

为了防止 new Example() 被错误地赋值给 Example<{ min: 1 }>,我们可以通过在构造函数中添加类型检查来确保 min 属性的存在。你可以使用一个类型断言来强制类型检查。

以下是一个可能的解决方案:

class Example<C extends Config> { example = true; constructor(private config: Readonly<C> = {} as C) { // 检查 config 是否包含 min 属性 if (!('min' in config)) { throw new Error("Config must include a 'min' property"); } } public min<const N extends number>(min: N) { return new Example<C & { min: N }>({ ...this.config, min, }); } }

代码解释

  • 类型检查: 在构造函数中,我们添加了一个简单的检查来确保 config 包含 min 属性。如果没有,我们抛出一个错误。这将阻止 new Example() 被错误地使用。

个人提示

  • 类型断言: 在 TypeScript 中,类型断言是一个强大的工具,但要小心使用。它可以帮助你绕过类型检查,但也可能导致意外的错误。
  • 类型推断: 有时候,显式地指定类型比依赖类型推断更安全,特别是在复杂的泛型场景中。

常见错误提醒

  • 忽略类型检查: 在使用泛型时,确保你理解 TypeScript 的类型推断机制,否则可能会导致类型不安全的代码。
  • 过度使用类型断言: 虽然类型断言可以解决很多问题,但过度使用可能会掩盖潜在的类型错误。

希望这能帮到你!如果你还有其他问题,随时问我哦!继续加油,TypeScript 的学习曲线虽然陡峭,但掌握后会让你的代码更健壮!🚀

如果你需要进一步的帮助,随时联系我!🙌

CloudFog API Gateway 🔥 New User Special

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

Claim Offer Now