Typescript:函数返回类型取决于字符串参数的值

标签 typescript

我想为 JavaScript 库编写类型,该库根据传递给它的字符串创建函数对象。

该函数应该是这样的:

function createResource(name: string): { /* How to write these types? */ } {
  return {
     [`create${name}`]: () => {},
     [`update${name}`]: () => {},
  }
}

这个想法是,给一个函数一个字符串(比如“todo”),该函数将返回一个对象

{
  createTodo: (todo: Todo) => void,
  updateTodo: (todo: Todo) => void
}

最佳答案

如果/当 microsoft/TypeScript#40336合并到 master 中(希望适用于 TS4.1),您将能够使用模板字符串类型来表示连接 "create""update 时发生的情况" 到为 name 传入的字符串。它看起来有点像这样:

function createResource<T extends string>(name: T) {
    return {
        [`create${name}`]: () => { },
        [`update${name}`]: () => { },
    } as { [K in `${"create" | "update"}${T}`]: () => void };
}

它会产生如下输出:

const resource = createResource("Todo");
/* const resource: {
    createTodo: () => void;
    updateTodo: () => void;
} */

请注意,`create${name}` 不会生成 "createTodo",除非 name"Todo" 带有大写的 “T”。可以使用 capitalize 修饰符将类型系统中的 "todo" 转换为 "Todo",但您的实现还需要改变...类似:

const cap = (s: string) => s.charAt(0).toUpperCase() + s.slice(1);
function createResource2<T extends string>(name: T) {
    return {
        [`create${cap(name)}`]: () => { },
        [`update${cap(name)}`]: () => { },
    } as { [K in `${"create" | "update"}${capitalize T}`]: () => void };
}

const resource2 = createResource2("todo");
/* const resource2: {
    createTodo: () => void;
    updateTodo: () => void;
} */

Playground link to code

关于Typescript:函数返回类型取决于字符串参数的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55346208/

相关文章:

typescript - 在 xcode 上编译应用程序时出现 ionic3 sqlite 错误

node.js - 无法在 typescript 构建中包含 .key 文件

javascript - 订阅后对象内的数组未定义

angular - 如何在 typescript 中编辑CSS样式?

html - 错误 NullInjectorError : R3InjectorError(AppModule)[Number -> Number -> Number]: NullInjectorError: No provider for Number

angular - 为 Angular 4 中的所有组件注入(inject)服务作为单例

Angular 将 html 模板作为字符串注入(inject)

parsing - 如何在静态方法中将 "promises"转换为 "string"[ts]

typescript - 如何声明 Rx.Observable.fromPromise() 的 TypeScript 返回类型

typescript : Type 'number' is not assignable to type '0'