【问题标题】:Create interface based on properties of other interfaces根据其他接口的属性创建接口
【发布时间】:2019-06-24 19:52:07
【问题描述】:

我有两个接口,WorkflowWorkflowVersion

workflow.model.ts

import { WorkflowVersion } from './workflow-version.model';

export interface Workflow{
    name: string;
    ID: number;
    workflowVersions: WorkflowVersion[];
}

workflow-version.model.ts

export interface WorkflowVersion{
    versionID: number;
    lastPublished: string;
    environmentID: number;
}

我想创建一个“扁平化”两者的界面。这个新接口WorkflowFlat 应该包含两个接口的所有非对象类型属性。目前我有这个:

workflow-flat.model.ts

export interface WorkflowFlat {
    name: string;
    ID: number;
    versionID: number;
    lastPublished: string;
    environmentID: number;
}

上面的模型实现了这一点,但感觉是重复的。如果我想在以后将description 属性添加到WorkflowVersion,我必须记住还要将其添加到WorkflowFlat。有没有办法让模型自动从两个接口中获取所有属性,然后用非对象接口创建一个新接口?

【问题讨论】:

标签: javascript typescript interface


【解决方案1】:

Aaron Beall 的答案很接近(抱歉,我还不能发表评论),但它没有正确删除扩展 object 的所有键,因此最终类型将需要它们为 key: never,即不想要。

以下 sn-p 通过重用来自很棒的 tycho01/typical repo 的类型级帮助器来实现目标:

export type NonMatchingPropNames<T, X> = { [K in keyof T]: T[K] extends X ? never : K }[keyof T];

export type NonMatchingProps<T, X> = Pick<T, NonMatchingPropNames<T, X>>;

type PrimitiveValuesOf<T> = NonMatchingProps<T, object>;

type A = PrimitiveValuesOf<Workflow & WorkflowVersion>;

const a: A = {
  name: '',
  ID: 0,
  versionID: 1,
  lastPublished: '',
  environmentID: 2
}; // OK

【讨论】:

  • 我错过了never 仍然出现,这个答案是正确的!
  • 我是 typescript 的新手,这是我第一次听说类型操作...我还有很多阅读要做!
  • 老实说,就类型级实用程序而言,这是我所能想到的:它们是提高代码库类型安全性的引人入胜且紧凑的方法,但很难判断是什么行为是 TS 的“公共 API”,而下一个版本可能会破坏。
猜你喜欢
  • 2018-10-17
  • 2016-02-23
  • 2021-12-20
  • 2012-12-06
  • 2021-06-28
  • 1970-01-01
  • 2010-09-23
  • 1970-01-01
相关资源
最近更新 更多