区分TypeScript中的记录和对象?

区分TypeScript中的记录和对象?,typescript,Typescript,我试图在TypeScript中创建一个条件类型,区分“记录”类型(其中键是无界/动态的)和普通对象类型(其中键是预定义的) 我可以获取类型的键,并检查一些希望不存在的属性: type R = { [x: string]: any } type O = { a: string; b: number } type IsRecord<T> = '__NEVER__' extends keyof T ? true : false type RR = IsRecord<R> /

我试图在TypeScript中创建一个条件类型,区分“记录”类型(其中键是无界/动态的)和普通对象类型(其中键是预定义的)

我可以获取类型的键,并检查一些希望不存在的属性:

type R = { [x: string]: any }
type O = { a: string; b: number }

type IsRecord<T> = '__NEVER__' extends keyof T ? true : false

type RR = IsRecord<R> // true
type OO = IsRecord<O> // false
type R={[x:string]:any}
类型O={a:string;b:number}
类型IsRecord=“\uuuuuu从不\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu?对:错
类型RR=IsRecord//true
类型OO=IsRecord//false
但这感觉有点不舒服。这是否可能以更简洁的方式实现?

可以通过检查
字符串本身是否是其键之一来识别
字符串

type IsRecord<T> = string extends keyof T ? true : false

type RR = IsRecord<R> // true
type OO = IsRecord<O> // false
如果您需要将
字符串
编号
索引标识为类似记录的索引,则只需检查
编号
,因为从键的角度来看,
编号
可分配给
字符串
。(这可能会令人困惑,但由于所有JS对象实际上都使用
string
symbol
键,因此每当您使用
number
对对象进行索引时,它首先被强制为
string
arr[0]
arr[“0”]
是相同的。TypeScript通过将所有
字符串
索引类型视为同时具有
字符串
数字
作为键来支持这一点。上面的链接对此进行了说明):

type IsNumericIndex=T的数量?对:错
类型RRR=IsNumericIndex//true
类型OOO=IsNumericIndex//false
类型NNN=IsNumericIndex//true


三元是不是在R的
中?真:假
必要吗?如果
“\uuuuuu从不\uuuuuu”扩展keyof R
返回一个
布尔值,则它是多余的。您也可以使用
!!(“从不”扩展keyof-O)
@AlexH对于条件类型,我认为这是必要的。但这只是伪代码,我对示例进行了编辑,希望能让它更清晰一些。我在寻找一个不涉及
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。非常感谢。
type IsRecord<T> = string extends keyof T ? true : false

type RR = IsRecord<R> // true
type OO = IsRecord<O> // false
type N = { [x: number]: any };
type NN = IsRecord<N>; // false
type IsNumericIndex<T> = number extends keyof T ? true : false

type RRR = IsNumericIndex<R> // true
type OOO = IsNumericIndex<O> // false
type NNN = IsNumericIndex<N> // true