CloudFog API Gateway

Limited Time

200+ AI Models Integration Hub

Claim Offer Now
Resolvedtypescript

TypeScript 类型问题:如何确保 `Example<{ min: 1 }>` 的严格类型检查?🤔

架构师Jack

1/12/2025

72 views7 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; test(new Example());

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

问题

我想要的是:

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

这行代码应该报错才对。有没有大佬能帮我看看这个问题怎么解决?🙏

PS: 我在 TypeScript Playground 上也试过了,结果还是一样。真是让人头疼啊!😅

感谢大家的帮助!❤️

标签:TypeScript, 泛型, 类型检查, 默认参数

1 Answers

程序员老张

1/12/2025

Best Answer13

Answer #1 - Best Answer

嘿,你好啊!👋

我太理解你遇到的这个 TypeScript 类型问题了!我之前也在类型系统上栽过跟头,尤其是当涉及到复杂的泛型和类型约束时。别担心,我们一起来看看怎么解决这个问题吧。

解决方案

你想要确保 Example<{ min: 1 }> 的严格类型检查,这意味着我们需要在类型系统中强制要求 min 属性的存在。为了实现这一点,我们可以利用 TypeScript 的条件类型和类型约束来确保类型的严格性。

代码示例

我们可以通过修改 Example 类的构造函数来实现这一点。具体来说,我们可以在构造函数中添加一个类型约束,确保 min 属性存在:

type Config = { min?: number; max?: number; }; class Example<C extends Config> { example = true; constructor(private config: Readonly<C> & { min: number } = {} as C & { min: number }) {} 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)); // 现在会报错

解释

  • 类型约束:在构造函数中,我们使用 Readonly<C> & { min: number } 来确保 min 属性的存在。这意味着任何传递给 Example 的配置对象都必须至少包含一个 min 属性。
  • 默认参数:我们使用 as C & { min: number } 来强制类型转换,这样即使没有提供参数,类型系统也会要求 min 属性。

个人提示

  • 常见错误:在使用泛型时,确保类型约束是你想要的。TypeScript 的类型推断有时会让人感到困惑,尤其是在处理可选属性时。
  • 调试技巧:使用 TypeScript 的 as const 和条件类型来帮助调试复杂的类型问题。

希望这些能帮到你!如果还有其他问题,随时问我哦!继续加油,TypeScript 的类型系统虽然复杂,但掌握之后会让你的代码更加健壮!💪

祝你好运!如果需要进一步的帮助,我随时在这儿!😊

CloudFog API Gateway 🔥 New User Special

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

Claim Offer Now