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

如何编写泛型以接收值必须为字符串的任意键接口?

问题描述

需要编写一个名为doThing的泛型函数,使用时需手动传入一个接口作为泛型参数。该接口可包含任意键,但所有值(包括可选值)必须为string类型;若接口中存在非string类型的值,TypeScript需抛出类型错误。示例代码如下:

function doThing<T extends ???>() {
  // do a thing
}

interface GoodInterface {
  foo: string
  bar?: string
}

interface BadInterface {
  foo: number
  bar: string
}

doThing<GoodInterface>() // 应正常运行
doThing<BadInterface>() // 应触发类型错误

最初尝试让泛型继承Record<string, string>,但出现错误:Index signature for type 'string' is missing in type 'GoodInterface'。不想为接口添加索引签名,请问该让泛型继承什么来实现此效果?

解决方案

可以使用映射类型作为泛型约束,替代Record<string, string>,这样无需为接口添加索引签名,同时确保所有属性值(包括可选属性)符合string类型要求(可选属性自动兼容undefined)。

修改后的函数定义如下:

function doThing<T extends { [K in keyof T]: string | undefined }>() {
  // do a thing
}

原理说明

  • { [K in keyof T]: string | undefined } 是映射类型,它会遍历泛型参数T的所有属性键K,要求每个键对应的属性类型必须是string或undefined——这正好匹配可选属性的本质(string | undefined)。
  • 与Record<string, string>不同,这个映射类型不需要目标接口拥有全局字符串索引签名,仅针对接口自身定义的属性做约束,完美适配显式定义属性的接口。

验证效果

  • doThing<GoodInterface>():GoodInterface的foo是string,bar是string | undefined,符合约束,正常运行。
  • doThing<BadInterface>():BadInterface的foo是number,不满足string | undefined的类型要求,TypeScript会抛出类型错误。

如果希望更严格地排除undefined(仅允许必填的string属性,可选属性也必须为纯string),可以调整约束为:

function doThing<T extends { [K in keyof T]: string }>() {
  // do a thing
}

此时GoodInterface的可选属性bar?: string会因为包含undefined触发错误,可根据实际需求选择。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 13:44:59