如何使参数只有在没有提供泛型的情况下才有条件?

type Params<T> = T extends Record<string, string> ? T : never;

export const getPath =
  <T>(path: string) =>
  (params: Params<T>) => {
    const lang = getCurrentLang();

    return generatePath(path, { lang, ...(params ?? {}) });
  };

例如:

const login = getPath("/:lang/login")
login() // should works without types error

const book = getPath<{ id: string }>("/:lang/books/:id")
book() // error
book({ id: "1" }) // works

推荐答案

您可以将泛型与条件类型结合使用,以强制getPath()的某个返回类型.让您泛型参数T扩展条件返回值的Union Type和不能赋予该值的值(例如undefined),这样您就可以判断是否传递了泛型参数.

If a generic argument was passed, return (param: T) => ... otherwise just () => .... This logic can be simplified even more using tuples in rest parameters and spread expressions:
(...params: T extends Record<string, string> ? [T] : [] ) => any

export const getPath = <
  T extends Record<string, string> | undefined = undefined
>(
  path: string
): ((
  ...params: T extends Record<string, string> ? [T] : []
) => any) => {
  return null as any; // ignoring the implemetation
};

const login = getPath("/:lang/login");
login(); // works

const book = getPath<{id: string}>("/:lang/books/:id");
//    ^? const book: (param: {id: string;}) => any
book(); // error
book({id: "1"}); // works

TypeScript Playground


附注:我删除了函数实现,因为我不知道getCurrentLang()generatePath()是如何定义的,也不知道它们的返回类型是什么.

Typescript相关问答推荐

使用React处理Websocket数据

在Typescribe中,extends工作,但当指定派生给super时出错""

我用相同的Redux—Toolkit查询同时呈现两个不同的组件,但使用不同的参数

如何通过TypeScript中的工厂函数将区分的联合映射到具体的类型(如类)?

有没有办法解决这个问题,类型和IntrinsicAttributes类型没有相同的属性?

在映射类型中用作索引时,TypeScrip泛型类型参数无法正常工作

对数组或REST参数中的多个函数的S参数进行类型判断

STypescript 件的标引签名与功能签名的区别

如何使默认导出与CommonJS兼容

是否存在类型联合的替代方案,其中包括仅在某些替代方案中存在的可选属性?

以Angular 自定义快捷菜单

如何创建一家Reduxstore ?

为什么ESLint会抱怨函数调用返回的隐式`any`?

TypeScrip错误:为循环中的对象属性赋值

在打字脚本中对可迭代对象进行可变压缩

如何键入';v型';

Karma Angular Unit测试如何创建未解析的promise并在单个测试中解决它,以判断当时的代码是否只在解决后运行

如何使用动态生成的键和值定义对象的形状?

Select 器数组到映射器的Typescript 泛型

Mongodb TypeError:类继承 events_1.EventEmitter 不是对象或 null