简体   繁体   English

如何正确处理多种类型的TypeScript值

[英]How to properly handle TypeScript values with multiple types

I have following TS interface 我有以下TS接口

export interface Item {
  product: string | Product;
}

When I want to literate through array of items I have to eliminate the type. 当我想通过数组项目进行识别时,我必须消除类型。 In other words 换一种说法

items = Items[];
items.forEach(item => {
  item.product._id
})

is not going to work because property is is not appliable to strings. 不会起作用,因为属性不适用于字符串。 Hence I have to pre-check the type, ie: 因此我必须预先检查类型,即:

items = Items[];
items.forEach(item => {
  if (typeof item.product === 'object') item.product._id
})

I don't really like how it looks. 我真的不喜欢它的样子。 How do you handle this situation? 你是如何处理这种情况的?

There should be type guards in order to narrow down the type: 应该有类型保护以缩小类型:

if (item.product && typeof item.product === 'object') item.product._id

Or: 要么:

if (item.product && typeof item.product !== 'string') item.product._id

If there's a possibility that item.product is a string as the interface suggests, this check is needed. 如果item.product可能是接口建议的字符串,则需要进行此检查。

Otherwise the type should be asserted: 否则应该声明类型:

items.forEach(item => {
  (item.product as Product)._id
})

Javascript doesn't type variables, so I imagine your issue is only about your IDE. Javascript没有输入变量,所以我想你的问题只是关于你的IDE。

The first and most obvious solution is to declare your variable as any . 第一个也是最明显的解决方案是将变量声明为any No further issue, but you won't have autocomplete. 没有其他问题,但您不会自动完成。

Second solution, not practical, is to create a typed variable : 第二个解决方案,不实用,是创建一个类型变量:

if (item instanceof Product) {
  _item: Product = item;
  // Now you have autocomplete on _item
} else if (typeof item === 'string') {
  _item: string = item;
  // Same here. 
}

This isn't practical because you will have to write 2 times your logic : once for the product, once for the string. 这是不切实际的,因为你必须写两次你的逻辑:一次是产品,一次是字符串。 But ! 但是! it may be not practical, but it is exhaustive, since you have to implement both logic (and they surely differ because you don't treat a string like an object, and vice versa). 它可能不实用,但它是详尽的,因为你必须实现两个逻辑(并且它们肯定会有所不同,因为你不像对象一样处理字符串,反之亦然)。

This may sound weird but the first/best approach should be "don't have a class variable with mixed type string | product". 这可能听起来很奇怪,但第一个/最好的方法应该是“没有混合类型字符串|产品的类变量”。

What is your specific use case? 你的具体用例是什么? Why are there some products as strings and some as classes? 为什么有些产品是字符串而有些是类? Is it possible to create an instance for the string classes as well? 是否可以为字符串类创建实例?

If this is somehow not possible for some reasons, you can check with instanceof for the proper type (do not check with typeof === 'object', as it is not really safe) 如果由于某些原因这是不可能的,你可以用instanceof检查正确的类型(不要检查typeof ==='object',因为它不是很安全)

if (item instanceof Product) { // do logic }}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM