首页 > 解决方案 > TypeScript 中有没有一种方法可以在不丢失对象特异性的情况下使用接口作为保护?

问题描述

我有一个问题,我试图在 TypeScript 中为共享模块创建一个接口,出于这个问题的目的,我们假设它具有以下形状:

interface A {
  x: string;
  y: { [name: string]: (...args: any) => {type: string; payload?: any} };
  z?: () => any
}

这个接口的目的有两个:

  1. 对于制作模块的人,我希望他们能够知道他们正在创建的东西符合 A。
  2. 对于使用该模块的人,我希望他们能够进行最具体的打字。

例如,如果我有:

const bar = {
  x: 'hello',
  y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) }
}

请注意缺少对 interface 的引用A

如果我要输入:bar.我会得到智能感知它具有属性xy. 更重要的是,在键入时,bar.y.我会得到提示world存在以及与之关联的函数类型。

但是,如果我添加A

const bar: A = {
  x: 'hello',
  y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) }
}

它有助于防止有人意外添加错误的属性,例如:

const bar: A = {
  iDontBelong: true, // wrong
  x: 'hello',
  y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) }
}

甚至

const bar: A = {
  x: 5, // wrong
  y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) }
}

现在的问题是,如果有人要导入bar并键入bar.,他们会得到直接针对 interface 的建议A。它失去了bar只有xy(和没有z)的知识,它也失去了关于y的特定类型的信息,这意味着它甚至不知道world存在于y

有没有办法让这两种东西同时存在?

标签: typescripttypesinterface

解决方案


有没有办法让这两种东西同时存在

只要你说: A那么你就不会得到对象包([name: string])中的东西的智能感知。

您可以通过不注释但进行类型测试来避免这种情况,例如:

const bar = {
  x: 'hello',
  y: { 'world': (a: string, b: number) => ({ type: a, payload: b}) }
}
const _ensureA: A = bar; // Type test 

推荐阅读