【问题标题】:Typescript: How to avoid repeating object declaration as a parameter?打字稿:如何避免重复对象声明作为参数?
【发布时间】:2021-08-05 04:05:35
【问题描述】:

动机

我想使用对象作为函数参数。这允许调用者使用指定的字段名称清楚地定义参数,从而更容易进行审查。

问题

但是,如果您使用implementsextends,这不是很好处理。这就是我现在正在做的。

src/domain/ServiceInterface.ts

export interface ServiceInterface {
  doesThings(args: {
    awesomeFieldName: string;
    isThisAwesomeFieldName?: string;
    ohWaitMoreAwesomeFieldName?: string;
  }): boolean;

src/domain/ComposedServiceInterface.ts

import { ServiceInterface } from "./domain/ServiceInterface";
export type ComposedServiceInterface = ServiceInterface & { hello: () => string };

src/implementations/ComposedServiceImplementation.ts

import { ComposedServiceInterface } from "./domain/ComposedServiceInterface";
export class ComposedServiceImplementation implements ComposedServiceInterface {
  doesThings(args: {
    awesomeFieldName: string;
    isThisAwesomeFieldName?: string;
    ohWaitMoreAwesomeFieldName?: string;
  }): boolean {
    return true;
  }
}

尝试

1。对象参数使用type/interface

src/domain/ServiceInterface.ts

export type DoesThingsParameter = {
    awesomeFieldName: string;
    isThisAwesomeFieldName?: string;
    ohWaitMoreAwesomeFieldName?: string;
  };
export interface ServiceInterface {
  doesThings(args: DoesThingsParameter): boolean;

src/domain/ComposedServiceInterface.ts

import { ServiceInterface } from "./domain/ServiceInterface";
export type ComposedServiceInterface = ServiceInterface & { hello: () => string };

src/implementations/ComposedServiceImplementation

import { ComposedServiceInterface } from "./domain/ComposedServiceInterface";
import { DoesThingsParameter } from "./domain/ServiceInterface";
export class ComposedServiceImplementation implements ComposedServiceInterface {
  doesThings(args: DoesThingsParameter): boolean {
    return true;
  }
}

Gripe:我不喜欢这个实现,因为 src/implementations/ComposedServiceImplementation 不需要从 importsrc/domain/ServiceInterface,因为它只实现了 ComposedServiceInterface

2。使用Parameter 实用程序类型

参考:https://www.typescriptlang.org/docs/handbook/utility-types.html#parameterstype

我似乎无法让 typescript 同意使用 Class 方法,例如Parameter<ComposedServiceInterface.doesThings>

有人可以提供任何建议吗?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    重用类型/接口的正确方法是 Attemp#1。每当您需要重用某些类型定义时,您都可以将其提取出来。如果您担心从src/domain/ServiceInterface 导入src/implementations/ComposedServiceImplementation,您可以随时为类型创建一个通用文件并在其中添加通用类型并在两个文件中导入。

    这里要注意的一点是,您只从src/domain/ServiceInterface 导入类型,因此在编译您的 TS 代码后,此导入将被清除。如果您想知道是否要导入值的类型,可以使用仅类型导入,例如: import type { DoesThingsParameter } from "./domain/ServiceInterface"; 这将使您的代码更具可读性。

    关于 Attemp#2,尽量避免过于频繁地使用复杂的实用程序类型,如 ParameterConstructorParameter,因为它们的实现非常复杂,Typescript 必须做很多工作。这些类型通常用于获取您无法直接访问的 args 的类型。 例如,如果您使用的库不提供 typescript 定义,并且您想使用该库中的函数。

    // some-library.ts
    export function configure({
     config1 = 'somevalue',
     retries = 1
    }) {
      ...code
    }
    

    现在你想使用这个configure函数但是想在外面创建一个配置对象。

    // helper.ts
    import { configure } from 'some-lib';
    
    const configuration = {
     config1: 'overrideValue',
     unknownProperty: 'unknownValue'
    }
    function helper() {
     const lib = configure(configuration)
    ...some work here
     }
    

    现在,配置具有configure 函数所需的所有属性,但它添加了configure 参数中不存在的一个新属性。在这种情况下,您必须使用 ParameterType 来获取configure args 的类型定义。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-25
    • 2018-11-06
    • 1970-01-01
    • 2020-01-08
    • 2021-01-20
    • 2017-08-12
    • 2020-09-12
    • 2019-05-26
    相关资源
    最近更新 更多