最近,我遇到了一个需要缩小具有联合类型属性的Obj的情况. 以下是我试图实现的简化版本.

interface typeA{
  id: number,
  status: 0 | 1,
}
interface typeB extends typeA {
  status: 1,
}

function log(param: typeB){
  // only accepts status = 1
}

但是,当try 对类型A的数据使用function log时,我会遇到以下错误:

Argument of type 'typeA' is not assignable to parameter of type 'typeB'.
  Types of property 'status' are incompatible.
    Type '0 | 1' is not assignable to type '1'.
      Type '0' is not assignable to type '1'

代码:

const data1: typeA = {id: 1, status: 0}

data1.status = 1

if(data1.status === 1){
  data1.status // when hovered, typescript can correctly identify that data1.status is 1
  log(data1) // error here
}

我现在像这样克服了错误,但我不确定是否有更好的打字操作符,所以解决我的问题

if(data1.status === 1){
  log({...data1, status: data1.status})
}

推荐答案

再加上1)如您所示构造一个即席对象(无论如何这是一个可接受的解决方案,但通常是不必要的额外编码),这里基本上还有两种其他方法:2)使用类型谓词[*]的"正确"方式;3)在TS中,您总是可以通过强制转换来强制术语的类型,在最坏的情况下,通过强制转换为any,这相当于对该术语以及任何包含该术语的表达式完全禁用类型判断.

以下分别是3)和2)的示例,从您所展示的代码开始:

interface typeA {
  id: number,
  status: 0 | 1,
}

interface typeB extends typeA {
  status: 1,
}

function log(param: typeB) {
  param.status;  // (property) typeB.status: 1
}

const data1: typeA = { id: 1, status: 0 };

if (data1.status === 1) {
  // here TS still considers `data1` of `typeA`
  // and has no reason to do otherwise, so we
  // force-cast, at our own risk and peril (!):
  log(data1 as typeB);  // cast
}

// this is a type predicate (see the return type):
function isTypeB(obj: typeA): obj is typeB {
  return obj.status === 1;
}

if (isTypeB(data1)) {
  // now TS *knows* `data1` is of `typeB`:
  log(data1);
}

[*]https://www.typescriptlang.org/docs/handbook/2/narrowing.html#using-type-predicates

Typescript相关问答推荐

如何在函数参数中使用(或模仿)`success`的行为?

为什么typescript要把这个空合并转换成三元?

在NextJS中获得Spotify Oauth,但不工作'

具有动态键的泛型类型

如何键入函数以只接受映射到其他一些特定类型的参数类型?

我可以为情态车使用棱角形的路由守卫吗?

适当限制泛型函数中的记录

Select 下拉菜单的占位符不起作用

从子类集合实例化类,同时保持对Typescript中静态成员的访问

刷新时保持当前名称的Angular

如何避免从引用<;字符串&>到引用<;字符串|未定义&>;的不安全赋值?

react 路由不响应参数

在类型脚本中创建显式不安全的私有类成员访问函数

typescript如何从映射类型推断

TypeScript:如何使用泛型和子类型创建泛型默认函数?

如何在TypeScript中描述和实现包含特定属性的函数?

TS2532:对象可能未定义

如何在Typescript 中定义具有相同类型的两个泛型类型的两个字段?

递归地排除/省略两种类型之间的公共属性

React 中如何比较两个对象数组并获取不同的值?