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

TypeScript如何定义禁止包含SecretString类型值的任意对象类型

解决方案

可以实现,以下是支持嵌套检查(覆盖对象、数组场景)的完整方案:

首先定义递归检查类型,只要类型中存在SecretString就返回never触发类型不兼容:

// 递归检查所有属性/元素,只要存在 SecretString 就返回 never
type NoSecrets<T> =
  T extends SecretString ? never :
  T extends object ? { [K in keyof T]: NoSecrets<T[K]> } :
  T;

修改日志函数的类型签名,要求传入的上下文参数必须符合无SecretString的规则:

type Logger = {
  info: <T extends object>(
    message: string,
    // 传入的context不符合无Secret规则时,类型不兼容触发编译报错
    context: T extends NoSecrets<T> ? T : never
  ) => void;
  // error、warn等其他日志方法同理修改签名即可
}

declare const logger: Logger;

效果验证

你给出的风险场景会直接触发编译错误:

const keys = decryptString(encryptedKeys);

// 编译报错:存在SecretString类型属性
logger.info('This should not compile!', { 
  valueThatIsOk: 'this is ok', 
  valueThatShouldFail: keys 
});

// 正常编译:无SecretString类型值
logger.info('Normal log', {
  publicStr: '公开内容',
  count: 123,
  nested: {
    foo: 'bar'
  }
});

// 嵌套场景也会触发报错
logger.info('Nested secret', {
  user: {
    password: keys // 此处有SecretString,触发报错
  }
});

// 数组包含SecretString也会触发报错
logger.info('Array secret', {
  secrets: [keys, '普通字符串'] // 此处有SecretString,触发报错
});

如果仅需要一级属性检查(不检查嵌套对象),可以用简化版本:

// 仅检查一级属性,不递归检查嵌套内容
type NoSecretsOneLevel<T extends object> = {
  [K in keyof T]: T[K] extends SecretString ? never : T[K]
}

// 对应修改日志函数签名即可
type Logger = {
  info: <T extends object>(
    message: string,
    context: T extends NoSecretsOneLevel<T> ? T : never
  ) => void;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 03:18:03