typescript - 不能在接口内使用自定义类型
问题描述
我似乎无法理解为什么我不能在界面中使用自定义类型。
我有以下定义:
type Operation = 'update'|'remove'|'add'
interface Rule {
op: Operation
path:string
value?:any
}
function applyDiff<Output>(rules: Rule[], obj: object): Output;
但我Type 'string' is not assignable to type 'Operation'
在这个失败的测试中收到一个错误:
const obj = {a: {b:1, c:2}}
const rules = [
{op: 'update', path: 'a.c', value:10},
]
const result = applyDiff(rules, obj)
但这段代码工作得很好:
function fn(x: number, y: 'add'|'remove'|'update'){
return x > 1 && y === 'add'
}
const result = fn(1, 'remove')
我在这里缺少什么?我将不胜感激有关此事的任何有用指导。谢谢你。
解决方案
首先,简单的解决方案:
const rules: Rule[] = [
// ^------^
{op: 'update', path: 'a.c', value:10},
]
但为什么一开始就不起作用呢?因为推断的类型rules
is {op: string; path: string; value: number}[]
,并且有很多string
s 不是Operation
联合中的任何值。对象和数组是可变的,因此没有什么可以阻止op
在定义rules
和传递它到applyDiff
.
这也提出了一些其他的解决方案:
将数组直接传递给函数:
const result = applyDiff([ {op: 'update', path: 'a.c', value:10}, ], obj);
在定义数组和将其传递给 之间,值无法更改,因此推断出
applyDiff
更窄的类型。{op: 'update'; path: 'a.c'; value: 10}[]
使用
const
断言显式缩小规则的类型:const rules = [ {op: 'update', path: 'a.c', value:10} as const, // ^-------^ ];
这告诉编译器您认为该对象是不可变的,这也导致它推断出更窄的类型
rules
。您可以改为显式缩小 的类型op
:const rules = [ {op: 'update' as const, path: 'a.c', value:10}, // ^-------^ ];
具有类似的效果。
推荐阅读
- php - 如何将while循环三个不同的变量放入json数组
- reactjs - 我想在有条件的本机反应中返回 2 个按钮
- jquery - 在按钮单击时添加水平手风琴
- java - 为什么在 Eclipse 控制台和调试器中都看不到 Java char 数组中的内容?
- javascript - 在 Chrome 控制台中,如何打印输入的数据?
- xamarin - Listview 在 xamarin 表单中从下到上滚动滞后问题
- android - 如何将 google play 开发者帐户转移到另一个 google 帐户?
- reactjs - 如何将 React 函数中的参数从一个文件传递到另一个文件
- abap - 将两个内部表连接并聚合为一张
- azure - Xamarin Android 构建在 AppCenter (Azure) 中失败并出现错误 APT0000