当前位置: 首页 > 知识库问答 >
问题:

switch语句 - 如何在 TypeScript 中根据动态值返回对应类型?

阎丰羽
2024-04-16

在 typescript 中如果根据动态值返回对应的类型.例如

type Params = {    type: 'human' | 'animal',    id: 'xxxxxx'}function test( val: Params) {    switch(val){        case 'human': return new A(val.id);        case 'animal': return new B(val.id);    }}// 这里的 result 并不会推导出 A,要怎么样才能让result推导得A呢?const result = test({ type: 'human', id: 1});

我像这么做并不可行

class A {  name: string;  constructor(val) {    this.name = val;  }}class B {  age: number;  constructor(val) {    this.age = val  }}function getValue(key: string) {  switch (val) {    case 'wxapp': return new A('hello');    case 'local': return new B(18);  }}const s = getValue('wxapp');

共有2个答案

翁和颂
2024-04-16

一个粗糙的方案:

class A {  name: string;  constructor(val) {    this.name = val;  }}class B {  age: number;  constructor(val) {    this.age = val;  }}function getValue(key: 'wxapp'): A;function getValue(key: 'local'): B;function getValue(key: 'wxapp' | 'local') {  switch (key) {    case 'wxapp':      return new A('hello');    case 'local':      return new B(18);  }}const a = getValue('wxapp');const b = getValue('local');
杨良平
2024-04-16

在 TypeScript 中,你可以使用泛型来实现基于动态值返回对应类型的功能。对于你给出的示例,你可以对 test 函数使用泛型,并在函数内部根据 Params 对象的 type 属性返回对应的类型。

下面是一个可能的实现方式:

type Params = { type: 'human' | 'animal', id: string | number}class A { name: string; constructor(val: string) { this.name = val; }}class B { age: number; constructor(val: number) { this.age = val; }}function test<T extends Params>(val: T): T['type'] extends 'human' ? A : T['type'] extends 'animal' ? B : never { switch (val.type) { case 'human': return new A(val.id as any); // 这里使用 any 断言是因为 val.id 的类型可能是 string | number,而 A 的构造函数参数需要是 string case 'animal': return new B(val.id as any); // 同上 default: throw new Error(`Unexpected type: ${val.type}`); }}const result = test({ type: 'human', id: 'JohnDoe' }); // result 的类型会被推导为 Aresult.name; // 可以访问 A 类的 name 属性const animalResult = test({ type: 'animal', id: 42 }); // animalResult 的类型会被推导为 BanimalResult.age; // 可以访问 B 类的 age 属性

在上面的代码中,我们使用了条件类型(Conditional Types)来根据 Params 对象的 type 属性返回对应的类型。当 type'human' 时,函数返回 A 类型;当 type'animal' 时,函数返回 B 类型。如果 type 是其他值,函数会抛出一个错误。

注意,在调用 new A(val.id as any)new B(val.id as any) 时,我们使用了 as any 断言。这是因为 val.id 的类型可能是 string | number,而 A 的构造函数参数需要是 stringB 的构造函数参数需要是 number。使用 as any 断言可以绕过类型检查,但需要注意确保传递的参数是正确的类型,以避免运行时错误。

此外,你还可以考虑使用工厂函数或工厂类来创建对象,这样可以根据传入的参数动态地创建和返回正确的类型。这样可以避免在 test 函数中使用 as any 断言,并使代码更加清晰和易于维护。

 类似资料:
  • 问题内容: 我正在将Golang Revel用于某些Web项目,到目前为止,我确实喜欢12个项目。由于返回类型,在所有这些代码中我都有很多代码冗余。看一下这两个功能: 如您所见,它们都返回相同类型的数据(类型struct)。我的想法只是像这样传递字符串var: 像这样,我只能使用一个助手来返回数据类型,而不是一遍又一遍地对不同的模型但相同的数据类型执行同一操作。 我的问题是: 这有可能吗 如果是,

  • 问题内容: 在Swift中,您可以使用’is’检查对象的类类型。如何将其合并到“ switch”块中? 我认为这是不可能的,所以我想知道解决此问题的最佳方法是什么。 问题答案: 您绝对可以在一个块中使用。请参阅Swift编程语言中的“对Any和AnyObject进行类型转换”(尽管当然不限于此)。他们有一个广泛的例子:

  • 演示: https://tsplay.dev/NB6axN 代码: 结果: 传入 '/posts' 拿到 Promise<string[]> 传入 '/test' 拿到 Promise<number[]> 前置条件: 尽可能不要强行断言

  • typescript,函数如何根据传入的key,返回对象对应的这些key?比如: 现在这个写法肯定不对,变量attr的推断是unknown,如何写函数getAttr的返回定义,才能让变量attr的推断为{age:number, name:string },就是函数传入了哪些key,就只返回这些key的推断

  • 我希望data是否必传由A[T]是否有必传属性决定。如何做呢?

  • 问题内容: 切换语句修复: switch语句仅返回最后一种情况,即情况4,“#0R0dfdf0FF”。我该如何解决这个问题,以使文本视图显示对话框中单击的那个?我是一个新手,所以真的很感谢您的帮助。 } 问题答案: 交换机分支的末尾缺少您。