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

TypeScript中如何限制函数参数允许传入的属性列表?

问题与解决方案

问题描述

定义了如下TypeScript接口:

export interface RegionNode {
    nodeSelected: boolean;
    nodeEditable: boolean;
    zone: Partial<Zone>;
    parent: RegionNode | null;
    children: RegionNode[];
}

想要实现一个递归设置节点及其子节点指定属性的函数,原实现如下:

function setNodeAndChildrenProperty(node: RegionNode, property: keyof RegionNode, state: boolean): void {
    // @ts-ignore
    node[property] = state;
    for (const child of node.children) {
        setNodeAndChildrenProperty(child, property, state);
    };
}

但不得不使用@ts-ignore,因为无法将传入的property参数限制为仅nodeSelected和nodeEditable这两个值为布尔类型的属性,需要优雅的解决方案。

解决方案

方案1:直接指定允许的属性字面量

直接将property的类型设为'nodeSelected' | 'nodeEditable',明确限定可传入的属性名称:

function setNodeAndChildrenProperty(node: RegionNode, property: 'nodeSelected' | 'nodeEditable', state: boolean): void {
    node[property] = state;
    for (const child of node.children) {
        setNodeAndChildrenProperty(child, property, state);
    }
}

这种方式简单直接,适合属性列表固定的场景,TypeScript会自动校验传入的属性是否在允许范围内,无需忽略类型检查。

方案2:通过类型工具动态提取布尔属性键

如果需要适配RegionNode中所有值为布尔类型的属性(包括未来新增的),可以定义一个类型工具来提取对应键:

// 提取对象中值为boolean类型的属性键
type BooleanKeys<T> = {
    [K in keyof T]: T[K] extends boolean ? K : never
}[keyof T];

function setNodeAndChildrenProperty(node: RegionNode, property: BooleanKeys<RegionNode>, state: boolean): void {
    node[property] = state;
    for (const child of node.children) {
        setNodeAndChildrenProperty(child, property, state);
    }
}

这个类型工具BooleanKeys会遍历T的所有键,只保留值类型为boolean的键。当RegionNode新增布尔类型属性时,函数会自动支持该属性,无需修改函数的参数类型定义。

内容的提问来源于stack exchange,提问作者Stéphane Gerber

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:50:16