首页 > 解决方案 > 描述参数的泛型类型,可以是少数类型之一

问题描述

这个问题主要来自我之前关于这个话题的一个问题:Declare a custom type for logical argument

这里有一个例子:

interface ProductType1 {
  id: string;
}

interface ProductType2 {
  productId: string
}

function getId(product: ???): string {
  return product.id || product.productId || string
}

这背后的想法是直截了当的:您可以传递一个类型ProductType1ProductType2产品 ID 本身的对象 ( string)

我试图做类似的事情:

type ProductAsArgument = ProductType1 | ProductType2 | string

或者

interface Product {
  id: string;
  productId: string;
}

或者

interface Product {
  id?: string;
  productId?: string;
}

但正如您可能猜到的那样,这些都不起作用,因为其中一个属性永远不会存在于其中一种联合类型 ( ProductType1, ProductType2, string)上

我相信我的首选选项是创建某种智能泛型,它将继承 a<T>并且会知道,它<T>可以是我上面提到的类型之一。我在这里可能错了,但在我看来,通用可以解决这个问题。

我在这里找到了一些有趣的方法How to make an generic type closelydependent on another in TypeScript? 但仍然不明白如何将其应用于我的案例

标签: typescript

解决方案


你可以使用类而不是接口吗?在这种情况下,您可以执行以下操作,尽管对 ProductType 类使用继承会更简洁:

使用类

class ProductType1 {
  id: string = '1';
}

class ProductType2 {
  productId: string = '2';
}

type ProductOrString = ProductType1|ProductType2|string;

function getId(product: ProductOrString): string {
  if (product instanceof ProductType1)
    return product.id;
  else if (product instanceof ProductType2)
    return product.productId;
  else if (typeof product === 'string')
    return product;
  else
    return 'Error in getId(): Unexpected type';
}

let prod1 = new ProductType1();
let prod2 = new ProductType2();
let prod3 = '3';

console.log(`prod1 ID is ${getId(prod1)}`);
console.log(`prod2 ID is ${getId(prod2)}`);
console.log(`prod3 ID is ${getId(prod3)}`);

TS Playground 链接


或者,使用接口:

使用接口

interface ProductType1 {
  id: string;
}

interface ProductType2 {
  productId: string;
}

type ProductOrString = ProductType1|ProductType2|string;

function getId(product: ProductOrString): string {
  if (typeof product === 'string')
    return product;
  else
  if ('id' in product)
    return product.id;
  else if ('productId' in product)
    return product.productId;
  else
    return 'getId(): Unexpected type';
}

let prod1 = { id: '1' };
let prod2 = { productId: '2' };
let prod3 = '3';

console.log(`prod1 ID is ${getId(prod1)}`);
console.log(`prod2 ID is ${getId(prod2)}`);
console.log(`prod3 ID is ${getId(prod3)}`);

推荐阅读