You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript泛型疑问:如何显式指定部分泛型并推断其余?

TypeScript:部分泛型参数显式声明,其余自动推断的实现方法

问题背景

我声明了Component常量,TypeScript能按预期推断其泛型类型。但我希望扩展组件的props类型(见ComponentWithExtraProp),可一旦声明其中一个泛型参数,TypeScript就会退出类型推断并报错:"Expected 4 type arguments"。目前看来我只能选择要么显式声明所有泛型参数,要么全部让其自动推断。有没有办法只声明其中一个(或部分)泛型参数,同时让其余参数自动推断?

示例代码

export const withStaticProps = <
  Props,
  Context,
  StaticProps,
  Component extends (props: Props & StaticProps) => string,
>(
  getStaticProps: (context: Context) => Promise<{ props: StaticProps }>,
  component: Component,
): Component & {
  getStaticProps: (context: Context) => Promise<{ props: StaticProps }>;
} => {
  return Object.assign(component, { getStaticProps });
};

const Component = withStaticProps(
  async ({ bar }: { bar: string }) => Promise.resolve({ props: { foo: bar } }),
  (props) => `Foo: ${props.foo}`, // Foo: astring
);

Component.getStaticProps({ bar: "astring" }).then((res) => {
  console.log(res.props.foo); // "astring"
});


const ComponentWithExtraProp = withStaticProps<{ extra: string }>( // Expected 4 type arguments, but got 1.
  async ({ bar }: { bar: string }) => Promise.resolve({ props: { foo: bar } }),
  (props) => `Foo: ${props.extra}`, // Property 'extra' does not exist on type 'Props & StaticProps'.
);

ComponentWithExtraProp.getStaticProps({ bar: "astring" }).then((res) => {
  console.log(res.props.foo); // 'res.props' is of type 'unknown'.
});

解决方案

方案1:使用TypeScript 4.7+的泛型占位符_

TypeScript 4.7及以上版本支持用_作为泛型参数的占位符,代表让编译器自动推断该参数的类型。修改ComponentWithExtraProp的调用方式即可:

const ComponentWithExtraProp = withStaticProps<{ extra: string }, _, _, _>(
  async ({ bar }: { bar: string }) => Promise.resolve({ props: { foo: bar } }),
  (props) => `Foo: ${props.extra}`,
);

这样既显式指定了Props类型为{ extra: string },剩余三个泛型参数由编译器自动推断,完美解决报错和类型推断失效的问题。

方案2:柯里化函数兼容低版本TypeScript

如果需要支持TypeScript 4.7以下版本,可将原函数改造成柯里化形式,先固定需要指定的泛型参数,再传入其他参数进行类型推断:

// 重构后的柯里化函数
export const withStaticProps = <Props>() => <
  Context,
  StaticProps,
  Component extends (props: Props & StaticProps) => string,
>(
  getStaticProps: (context: Context) => Promise<{ props: StaticProps }>,
  component: Component,
): Component & {
  getStaticProps: (context: Context) => Promise<{ props: StaticProps }>;
} => {
  return Object.assign(component, { getStaticProps });
};

// 使用方式
const ComponentWithExtraProp = withStaticProps<{ extra: string }>()(
  async ({ bar }: { bar: string }) => Promise.resolve({ props: { foo: bar } }),
  (props) => `Foo: ${props.extra}`,
);

通过柯里化拆分调用步骤,先锁定Props类型,后续参数的泛型类型仍能被自动推断,满足部分指定的需求。


内容的提问来源于stack exchange,提问作者nomadoda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 01:30:09