Typescript接口上的动态属性键和值依赖于其他字段

Typescript接口上的动态属性键和值依赖于其他字段,typescript,Typescript,我是Typescript新手,我想知道是否有办法实现以下目标: 我想键入几个属性,通过它们的两个不同端点发送到Hubspot,每个API使用名为property的键和名为name的键接收数据。 这意味着它们可以像这样: { property: 'email', value: 'test@email.com' } 或: 然后,我想确认我只发送了一些特定的字段。说: export interface HubspotFields { newsletter: boolean; name

我是Typescript新手,我想知道是否有办法实现以下目标:

我想键入几个属性,通过它们的两个不同端点发送到Hubspot,每个API使用名为
property
的键和名为
name
的键接收数据。 这意味着它们可以像这样:

{
  property: 'email',
  value: 'test@email.com'
}
或:

然后,我想确认我只发送了一些特定的字段。说:

export interface HubspotFields {
  newsletter: boolean;
  name: string;
  email: string;
}
那么,有没有办法做到这一点

export interface Test {
  [either "property" or "name"]: [keyof HubspotFields (value can only be one of the keys from HubspotFields)];
  value: [the type of the corresponding dynamic keyof HubspotFields (string 
 boolean)];
}
换言之:

//This fails
{
  something: 'email',
  value: 'test@email.com'
}
//This fails
{
  property: 'something',
  value: 'test@email.com'
}
//This fails
{
  property: 'email',
  value: 2312
}
//This passes
{
  property: 'newsletter',
  value: true
}
//This passes
{
  name: 'email',
  value: 'test@email.com'
}

希望我想要完成的事情足够清楚,如果不是,我很乐意详细说明。提前谢谢

我认为,以下类型可以满足您的需求:

// ensure return type of boolean or string
type StringOrBoolReturn = {
  [K: string]: boolean | string
}

export interface HubspotFields extends StringOrBoolReturn {
  newsletter: boolean;
  name: string;
  email: string;
}

// support either property XOR name
type ApiData<K extends keyof HubspotFields = keyof HubspotFields> = {
  property: K
  name?: never
  value: HubspotFields[K]
} | {
  property?: never
  name: K
  value: HubspotFields[K]
}
//确保返回类型为布尔值或字符串
类型StringOrBoolReturn={
[K:字符串]:布尔|字符串
}
导出接口HubspotFields扩展StringOrBoolReturn{
通讯:布尔;
名称:字符串;
电子邮件:字符串;
}
//支持属性XOR或名称
类型ApiData={
物业:K
名字?:从来没有
值:hubspottfields[K]
} | {
财产?:永远不会
姓名:K
值:hubspottfields[K]
}
函数sendApiData(data:ApiData){/*…逻辑…*/}
sendApiData({something:'email',value:'test@email.com' }) // ✖
sendApiData({property:'something',value:'test@email.com' }) // ✖
sendApiData({property:'email',value:2312})//✖
sendApiData({name:'email',属性:“email”,值:'test@email.com' })  // ✖
sendApiData({property:'newsletter',value:true})//✔
sendApiData({name:'email',值:'test@email.com' })  // ✔
sendApiData({name:'email',值:'test@email.com' })  // ✔
// ensure return type of boolean or string
type StringOrBoolReturn = {
  [K: string]: boolean | string
}

export interface HubspotFields extends StringOrBoolReturn {
  newsletter: boolean;
  name: string;
  email: string;
}

// support either property XOR name
type ApiData<K extends keyof HubspotFields = keyof HubspotFields> = {
  property: K
  name?: never
  value: HubspotFields[K]
} | {
  property?: never
  name: K
  value: HubspotFields[K]
}
function sendApiData<K extends keyof HubspotFields>(data: ApiData<K>) {/*... logic ...*/}

sendApiData({ something: 'email', value: 'test@email.com' }) // ✖
sendApiData({ property: 'something', value: 'test@email.com' }) // ✖
sendApiData({ property: 'email', value: 2312 }) // ✖
sendApiData({ name: 'email', property: "email", value: 'test@email.com' })  // ✖
sendApiData({ property: 'newsletter', value: true }) // ✔
sendApiData({ name: 'email', value: 'test@email.com' })  // ✔
sendApiData({ name: 'email', value: 'test@email.com' })  // ✔