Typescript 打字稿—;确保对象道具关键点与道具值相同

Typescript 打字稿—;确保对象道具关键点与道具值相同,typescript,Typescript,我需要键入以下对象结构: const entities = { abc: { id: 'abc' }, def: { id: 'def' } } 每个对象道具关键点都需要与其对应的id匹配 我试着这样做: interface EntitiesMap<E extends Entity> { [K in E['id']]: E; } interface Entity { id: string; } 你知道我该怎么做吗?那是因为你把id定义为

我需要键入以下对象结构:

const entities = {
  abc: {
    id: 'abc'
  },
  def: {
    id: 'def'
  }
}
每个对象道具关键点都需要与其对应的
id
匹配


我试着这样做:

interface EntitiesMap<E extends Entity> {
  [K in E['id']]: E;
}

interface Entity {
  id: string;
}

你知道我该怎么做吗?

那是因为你把
id
定义为
string
'aaaaaa'
是一个字符串。您可以对
id
使用类似的内容,这比
string
更具体:

type IdType = keyof typeof entities // "abc" | "def"

// and use it as id type

interface Entity {
  id: IdType
}

这也许不是你想要的确切答案,但这是一个好的开始。希望对您有所帮助

如果您可以使用identity函数创建实体,您可以使用泛型来推断根键和映射类型,以验证内部对象的值:

const createEntities = <TKeys extends string>(entities: { [K in TKeys]: { id: K } }) => entities;

// OK
const entities = createEntities({
  abc: {
    id: 'abc'
  },
  def: {
    id: 'def'
  }
})

// Error: type '"aaaaa"' is not assignable to type '"ghi"'
createEntities({
  ghi: {
    id: 'aaaaa'
  }
})
constcreateentities=(entities:{[K-in-TKeys]:{id:K})=>entities;
//嗯
常量实体=创建实体({
abc:{
id:'abc'
},
定义:{
id:'def'
}
})
//错误:类型“aaaaa”不可分配给类型“ghi”
创建实体({
ghi:{
id:'aaaaa'
}
})

我知道的方法是定义一个类型。但你需要时刻关注钥匙

类型实体={
[K in T]:{
id:K;
};
};
常量实体:实体={
abc:{
id:'abc'
},
定义:{
id:'def'
},
def2:{

id:'abc'/我认为使用简单的类型签名是不可能的,但是如果您使用
实体
声明为常量
,则完全可以在类型级别执行此操作,而无需任何JavaScript函数:

type ValidEntities<E> = {[K in keyof E]: {id: K}}
type IsValid<E extends ValidEntities<E>> = true // Can be any type

// OK
const entities = {
  abc: {
    fine: 3,
    id: 'abc'
  },
  def: {
    id: 'def'
  }
} as const

type Validate = IsValid<typeof entities>
type ValidEntities={[K in keyof E]:{id:K}
type IsValid=true//可以是任何类型
//嗯
常量实体={
abc:{
罚款:3,,
id:'abc'
},
定义:{
id:'def'
}
}常量
类型Validate=IsValid
如果
实体
无效,您将在
IsValid
处得到一个类型错误


谢谢,我也试过一些类似的方法,但是卡住了。谢谢你的建议。这是个好主意。我会考虑的。你知道如果没有创建函数,它是可能的吗?如果你知道前面的键-是的。
type ValidEntities<E> = {[K in keyof E]: {id: K}}
type IsValid<E extends ValidEntities<E>> = true // Can be any type

// OK
const entities = {
  abc: {
    fine: 3,
    id: 'abc'
  },
  def: {
    id: 'def'
  }
} as const

type Validate = IsValid<typeof entities>