映射类型:删除私有接口

2024-02-27

在 TypeScript 中,私有属性被视为类型的形状(或接口)的一部分。

class Person {
  constructor(private name: string, public age: number) { }
}
const p: Person = { age: 42 };
// Error: Property 'name' is missing.

这是有效的,因为 TypeScript 需要跟踪私有变量。

class Person {
  constructor(private name: string, public age: number) { }
  equals(other: Person) {
    return this.name === other.name && this.age === other.age;
    // This is valid, because TypeScript kept track of the private `name` property!
  }
}

但是,通常您想忽略私有接口。例如,当您使用依赖项注入和单元测试时。

class HttpClient {
   constructor(private log: Logger) {
   }
   async doGet(url: string) { 
      return (await fetch(url)).json();
   }
}

class MyService {
  constructor(private http: HttpClient) {
  }
  // Implementation
}

// Unit test for MyService:
describe('MyService', () => {
  it('should work', () => {
    const httpMock: HttpClient = { // ERROR: Property 'log' is missing
      doGet(url: string) {
         return Promise.resolve({ name: 'Han' });
      }
    };
    const sut = new MyService(httpMock);
  });
});

我知道我们可以通过添加接口来解决这个问题IHttpClient它描述了一个公共接口HttpClient并直接使用它而不是类类型,但这需要大量工作,并且需要手动保持同步。

有没有办法使用映射类型从类型中删除所有非公共属性?

就像是:

type PublicInterface<T> = {
    [P in PublicNames<T>]: T[P];
}

所以它可以用在你不关心隐私的地方:

class MyService {
  constructor(private http: PublicInterface<HttpClient>) {
  }
  // Implementation
}

keyof足够聪明,只能查看公钥:

class Person {
  constructor(private name: string, public age: number) { }
}

type PublicInterface<T> = {
    [P in keyof T]: T[P];
}

const p: PublicInterface<Person> = { age: 42 }; // no error

操场 https://www.typescriptlang.org/play/index.html#code/MYGwhgzhAEAKCmAnCB7AdtA3gKGtY6EALogK7BEqIAUADogJYBuYR80aYAtvAFzTFGaAOYAaaLVIAjEA2DQwwvh1JcpSAJRZoAX2x7sRAJ612sabOABJNG0QAzMMHgAeACoA+aAF4suaADasNAMGADW8EYo9tBuALr8bkFxANz62NgEaMQS-OYycjZ2js4uCMjoXr6YCkr8ACwATLop0AD0bRwo0EiIVEA


或者甚至更短Pick https://www.typescriptlang.org/docs/handbook/utility-types.html#picktk实用程序(结果相当于上面的映射类型):

type PublicInterface<T> = Pick<T, keyof T>;

操场 https://www.typescriptlang.org/play/index.html#code/MYGwhgzhAEAKCmAnCB7AdtA3gKGtY6EALogK7BEqIAUADogJYBuYR80aYAtvAFzTFGaAOYAaaLVIAjEA2DQwwvh1JcpSAJRZoAX2x7sRAJ612sabOABJNG0QAzMMHgAeACoA+aAF44cgNbu4v7wRij20J4A3NjYBGjEEvzmMnI2do7OLgjI6F6+mApK-AAsAEy6UdAA9NUcKNBIiFRAA

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

映射类型:删除私有接口 的相关文章

随机推荐

  • OpenGL重叠丑陋的渲染

    我正在尝试使用 OpenGL 2 1 渲染场景 但重叠形状的边框很奇怪 我测试了一些 OpenGL 初始化 但没有任何改变 我将问题简化为一个简单的测试应用程序 其中有 2 个球体 但结果相同 我尝试了一些关于 Gl DEPTH TEST
  • 警告:未找到提供程序 com.sun.xml.internal.bind.v2.ContextFactory

    我在 JSF 应用程序中集成了一些 Web 服务Jersey 一切正常 甚至 OAuth 识别也正常 但 当启动我的网络服务器时 我总是收到此错误 INFO Scanning for root resource and provider c
  • csrf 与 ajax 和 django post

    使用jquery v1 7 1和django 1 3 我试图通过ajax发出post请求 在我找到的一些教程代码中web http lethain com intro to unintrusive javascript with djang
  • 如何获取javafx中子节点的访问权限?

    我有一棵这样的树 正如您所看到的 GridPane 有 10 列 它们每个都包含包裹在 AnchorPane 中的 BorderPane 每个 BorderPane 由 2 个标签和 1 个单选按钮组成 您可以在下面看到它的样子 我想问您如
  • 如何从 javascript HTMLCollection 获取元素

    我不明白为什么我无法从 HtmlCollection 获取元素 此代码示例 var col document getElementsByClassName jcrop holder console log col 在控制台上产生以下输出 我
  • cv::warpPerspective 仅显示扭曲图像的一部分

    我使用 getHomography 和 warpPerspective 将图像从前视角更改为中视角 它的工作原理是图像扭曲到所需的视角 但裁剪被关闭 它将扭曲的图像大部分移动到图像框之外 我认为原因是因为操作导致负坐标 我已经手动计算了用于
  • Web API 令牌方案的好方法是什么?

    我正在为一个 Web 应用程序开发 REST API 到目前为止 我们已经在内部为几个配套应用程序开发了该 API 现在 我们正在考虑向外部开发人员开放 我们希望向 API 添加令牌 以帮助识别谁在发出请求 并总体上帮助管理其使用 此时 我
  • Jinja2 填充和对齐字符串

    我想实现类似的目标 https pyformat info string pad align https pyformat info string pad align 在 Jinja2 中 在 python 中 如果我希望字符串始终具有一定
  • 类型推断失败:没有足够的信息来推断参数请明确指定

    我正在尝试用 Kotlin 编写 Vaadin 应用程序 对于数据绑定 Vaadin 8 现在提供了类型安全数据绑定的可能性 在 Kotlin 中 我期望这样的工作 class LoginModel var username String
  • Formik 验证 isSubmitting / isValidating 未设置为 true

    我有一个用户要求的表格 我非常明显地表明该表格无效 所以我打算弹出一个sweetalert对话框让他们知道他们需要仔细检查表格 我想我可以在验证中这样做 以便在提交尝试失败时提醒他们 const validate values gt con
  • VBScript 中的 CRLF

    我是 VBScript 新手 我正在尝试编写一个函数来识别打印行中是否有 CRLF 你能帮我么 谢谢 你可以简单地使用result Instr yourString vbCRLF 如果 CRLF 字符序列存在于中 它将返回大于 0 的索引y
  • 如何在javascript中为隐藏变量分配空值?

    我有一个名为 str 的隐藏输入变量 我正在为其分配 abc 值 然后我尝试分配空值 或者说对它的空引用 但我不能 Edit 代码的一部分 隐藏领域
  • 为什么哈希的字符串键被冻结?

    根据规格 http www ruby doc org core 1 9 3 Hash html method i store 用作哈希键的字符串被复制并冻结 其他可变对象似乎没有这样特殊的考虑 例如 使用数组键 可以进行以下操作 a 0 h
  • 开玩笑,在 GitLab 上找不到命令

    我想在 GITLAB 上使用 JEST 执行单元测试 但它似乎不起作用 它可以在我的本地计算机上运行 但不能在 GitLab 上运行 整个代码为 gitlab ci yml image node 16 cache paths node mo
  • exec sp_updatestats 的作用是什么?

    有什么用sp updatestats 我可以在生产环境中运行它以提高性能吗 sp updatestats更新数据库中所有表的所有统计信息 甚至单行已更改 它使用默认示例来执行此操作 这意味着它不会扫描表中的所有行 因此它可能会生成不如替代方
  • 如何从两个制表符分隔的文件中获取枢轴线?

    给定两个文件file1 txt abc def t 123 456 jkl mno t 987 654 foo bar t 789 123 bar bar t 432 and file2 txt foo bar t hello world
  • 更新具有空值的多行

    我有一个包含 id 和 name 两列的表 Id 包含空值 name 包含一些名称值 表中存在重复的行 要求是将空值 id 更新为与名称值匹配的某个值 查找下表 Id Name 1 abc 1 abc 1 abc 1 abc NULL ab
  • 将表重新添加到实体模型 (edmx) 时不显示

    我有一个有 5 个表的数据库 一开始 我添加了这些表 但后来由于某些关系编译错误而决定删除一些表 现在 当我想将它们添加回来时 我打开 edmx 文件 gt 从数据库更新模型 我在 添加 选项卡下看不到这些表 而只在 刷新 选项卡下看到 我
  • Tensorflow:张量到 numpy 数组的转换,无需运行任何会话

    我在张量流中创建了一个OP 对于某些处理 我需要将数据从张量对象转换为numpy数组 我知道我们可以使用tf eval or sess run评估任何张量对象 我真正想知道的是 有没有办法在不运行任何会话的情况下将张量转换为数组 因此我们又
  • 映射类型:删除私有接口

    在 TypeScript 中 私有属性被视为类型的形状 或接口 的一部分 class Person constructor private name string public age number const p Person age 4