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

能否让TypeScript编译器对不符合参数必填要求的函数赋值报错?

能否让TypeScript在函数赋值不符合参数必填要求时抛出错误?

需求:希望TypeScript编译器在函数赋值不符合原函数的参数必填要求时抛出错误,示例代码如下:

function f(r: number, o?: string) {}

type HasRequiredProps<F> = 
    F extends (...args: infer A) => any 
        ? A['length'] extends 1 | 0 
            ? false
            : true
    : false;

type R = HasRequiredProps<typeof f> extends true 
    ? (p: number) => void
    : (p?: number) => void

// 此处期望触发错误,但实际没报错
const ff: R = function () {
    
}

这个需求可以实现,但你当前的类型逻辑存在两个问题:

  1. HasRequiredProps仅通过参数数组长度判断是否有必填项,逻辑不准确——比如参数长度为2但其中只有1个必填项的情况,它会误判;
  2. TypeScript默认的函数赋值遵循逆变规则:允许少参数的函数赋值给多参数的类型(因为调用时会传入足够参数,少参数的函数会忽略多余部分),所以即使R定义为(p: number) => void,赋值无参函数也不会报错。

修正方案

要实现严格的必填参数检查,需要先提取原函数的所有必填参数,再约束赋值的函数必须包含这些参数。示例代码如下:

function f(r: number, o?: string) {}

// 提取函数的所有必填参数类型
type RequiredArgs<F> = F extends (...args: infer A) => any 
  ? FilterRequired<A>
  : never;

// 递归过滤出数组中的必填项(排除可选参数)
type FilterRequired<T extends any[]> = T extends [infer First, ...infer Rest]
  ? First extends undefined 
    ? FilterRequired<Rest>
    : [First, ...FilterRequired<Rest>]
  : [];

// 根据原函数是否有必填参数,定义目标类型
type R = RequiredArgs<typeof f> extends []
  ? (p?: number) => void
  : (...args: RequiredArgs<typeof f>) => void;

// 此处会触发TypeScript错误,符合预期
const ff: R = function () {};

说明

  • RequiredArgs和FilterRequired组合作用,精准提取原函数中所有必填的参数类型(比如示例中会提取出[number]);
  • 当原函数有必填参数时,R会要求赋值的函数必须接收这些必填参数,打破了默认的逆变规则限制,从而在赋值不符合要求的函数时抛出错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 22:57:35