如何在Typescript中将类型转换为接口

8
在TypeScript中有没有一种方法可以将一个`type`转换为一个`interface`?
我已经阅读了这个StackOverflow上的问答,但我认为它与我在这个问题中描述的情况不太匹配。
下面是一个快速示例,展示了一个场景,其中一个`Product`被定义为来自第三方TypeScript库的`type`。
// ProductFragmentOne is used to highlight the possibility of composition(unions, etc)
type Product = ProductFragmentOne & { sku: string };

要将那个产品整合到我们自己的系统中,可以通过扩展(联合)一个类型来实现,如下面的示例所示:
export type ProductSchema = Product & { 
  name: string;
}

我的问题是:

  • 我们的ProductSchema有没有办法被定义为一个接口?这可行吗?
# Example of how the code may look
export interface ProductSchema{ 
  name: string;
  //Do the magic to add Product properties here
}

更新:采用这种方法的原因纯粹是因为对interface而非type的偏好。这样可以使现有代码保持其风格,无论采用了哪个第三方库。

谢谢。


1
不,可能不行。仅当 type 已经是一个对象类型(或对象类型的交集),其键是静态已知的时,你才能从 type 创建一个 interface 。由于 Product 是一个联合类型,它不满足这个限制。当然, { ... } 不是实际的代码,所以这不是我可以确定的 [mcve] 一种方式或另一种方式。你为什么还想要一个 interface?你是否因为某种原因需要它?还是只是出于个人喜好? - jcalz
1
这并没有什么实际原因,因为几乎所有可以使用接口完成的操作也可以使用类型完成。如果Product是一个联合类型,那么可能有理由这样做,即使你可以定义一个基础接口,让两种类型的Product对象都扩展它,但很可能会出现一些情况,你可以创建一个可分配给基础接口但无法分配给Product的对象,因为它基于两种Product类型的冲突部分。你不想要那样。你不想这样做。 - Linda Paiste
我在问题中更新了两个先前评论的更多澄清。人们编写代码的方式不同,一个项目中使用的风格不应影响对其有依赖的项目的编写(结构)方式。 - P.M
1个回答

14
为了解决这个问题,我使用了在一个完全无关的问题上找到的答案:它是否"可能扩展Typescript中的类型"
实际上,自从TypeScript 2.2以来,一个接口可以扩展一个类型。
在这个 StackOverflow 线程中有一个详细讨论接口和类型之间的区别:TypeScript:接口 vs 类型
export interface ProductSchema extends Product{ 
  name: string;
}

// Where the Product is a type similar to
type Product = { SKU: string }

我正在寻找的“魔术技巧”确实是那个extends运算符(或关键字)。 还有一个基于相同方法的示例在TypeScript playground上也有。

1
有没有什么技巧可以避免声明单独的类型定义,这样我们就可以做到 export interface ProductSchema extends typeof ProductObj { name: string; } - chrismarx
2
可能需要指出的是:「接口只能扩展具有静态已知成员的对象类型或对象类型的交集。ts(2312)」因此,以下结构不起作用:const ctype: Readonly<string[]> = ["a", "b"] as const; type ttype = typeof ctype[number]; interface xyz extends ttype {…} - Denis Giffeler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接