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

如何为函数定义类型以仅接受映射到特定类型的参数类型?

问题

我要写一个函数,传入字段名就能检查该字段是否为必填项,要求这个函数只接受Config类型中对应配置包含required属性的字段名。目前我已经有一个可行方案——通过定义ValidationField类型来约束函数参数:

type Field = 'name' | 'surname' | 'age' | 'height' | 'school';

type ValidationField = Extract<Field, 'name' | 'surname'>;
type RequiredConfig = {required?: boolean};
type ValidationConfig<T> = T extends ValidationField ? RequiredConfig : {};

type Config = {
    [K in Field]?: ValidationConfig<K> & {visible?: boolean};
}

const config: Config = {name: {required: true, visible: true}, surname: {required: true, visible: true}, age: {visible: false}}

const checkRequired = (field: ValidationField) => config[field]?.required

但现在的情况是,我无法访问ValidationField类型,只能用Config、ValidationConfig和RequiredConfig这几个类型,请问有没有办法实现同样的参数约束效果?比如能不能像下面这样通过条件类型来约束泛型参数:

const checkRequired = <T extends Field>(field: Config[Field] extends ...? T : never) => config[field]?.required

解决方案

完全可以实现,核心是通过TypeScript的条件类型+键遍历,从Config中直接过滤出对应值兼容RequiredConfig的字段名,不需要依赖ValidationField。

方案一:先提取合法字段类型,再用于函数参数

type Field = 'name' | 'surname' | 'age' | 'height' | 'school';

type RequiredConfig = {required?: boolean};
type ValidationConfig<T> = T extends any ? (Extract<keyof Config, T> extends 'name' | 'surname' ? RequiredConfig : {}) : {};

type Config = {
    [K in Field]?: ValidationConfig<K> & {visible?: boolean};
}

const config: Config = {name: {required: true, visible: true}, surname: {required: true, visible: true}, age: {visible: false}}

// 从Config中筛选出对应值包含required属性的字段
type ValidRequiredField = keyof {
  [K in keyof Config as Config[K] extends RequiredConfig ? K : never]: unknown
}

const checkRequired = (field: ValidRequiredField) => config[field]?.required

方案二:直接在函数泛型中做约束(更简洁)

不需要单独定义ValidRequiredField,直接在函数的泛型参数里完成过滤:

const checkRequired = <T extends keyof Config>(
  field: T extends (Config[T] extends RequiredConfig ? T : never) ? T : never
) => config[field]?.required

两种方案都能让checkRequired函数只接受name和surname作为参数,和原来依赖ValidationField的效果完全一致,且没有使用ValidationField类型。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 13:42:45