Typescript 记录之间的差异<;键,类型>;和[键:字符串]:类型

Typescript 记录之间的差异<;键,类型>;和[键:字符串]:类型,typescript,typescript-utility,Typescript,Typescript Utility,我想知道记录和[键:字符串]:键入之间的区别。我们可以互换使用吗?哪个更具动态性和类型安全性 我举了一个例子,我将两者交替使用。哪一个是好的实践 //Record example interface PageInfo { title: string; } type Page = "home" | "about" | "contact"; const nav: Record<Page, PageInfo> = {

我想知道
记录
[键:字符串]:键入
之间的区别。我们可以互换使用吗?哪个更具动态性和类型安全性

我举了一个例子,我将两者交替使用。哪一个是好的实践

//Record example
interface PageInfo {
  title: string;
}

type Page = "home" | "about" | "contact";

const nav: Record<Page, PageInfo> = {
  about: { title: "about" },
  contact: { title: "contact" },
  home: { title: "home" },
};

console.log(nav.about);
// object example

type Page2 = {
  [key: string]: PageInfo;
};

const navHtml: Page2 = {
  about: { title: "about" },
  contact: { title: "contact" },
  home: { title: "home" },
};

console.log(navHtml.contact);
//记录示例
界面页面信息{
标题:字符串;
}
键入Page=“home”|“about”|“contact”;
常数导航:记录={
关于:{title:“关于”},
联系人:{title:“联系人”},
主页:{标题:“主页”},
};
控制台日志(导航关于);
//对象示例
类型第2页={
[键:字符串]:页面信息;
};
常量navHtml:Page2={
关于:{title:“关于”},
联系人:{title:“联系人”},
主页:{标题:“主页”},
};
console.log(navHtml.contact);

首先,好吧,没有一个是完全类型安全的

您可以将联合类型用作记录-
记录
中的
键,但在索引类型中不能使用:

类型第2页={
[key:string | number | symbol]:PageInfo;//错误
};
范例

//记录示例
界面页面信息{
标题:字符串;
}
键入Page=“home”|“about”|“contact”;
常数导航:记录={
关于:{title:“关于”},
联系人:{title:“联系人”},
主页:{标题:“主页”},
};
控制台日志(导航关于);
//对象示例
类型第2页={
[键:字符串]:页面信息;
};
常量navHtml:Page2={
关于:{title:“关于”},
联系人:{title:“联系人”},
主页:{标题:“主页”},
};
console.log(navHtml.contact);
/**
*如果您有一个字符串作为键-没问题
*/
类型Test1=记录扩展{[p:string]:string}?真:假//真
类型Test2={[p:string]:string}扩展记录?真:假//真
常量foo=(arg:Record)=>arg
常数索引:{[p:string]:string}={bar:'bar'}
foo(索引)//无错误
/**
*反之亦然
*/
常量条=(arg:{[p:string]:string})=>arg
常量记录:记录={bar:'bar'}
foo(record)//没有错误
/**
*但是如果您有一个联合类型作为键
*上述方法行不通
*/
类型Test3=记录扩展{[p:string]:string}?真:假//真
类型Test4={[p:string]:string}扩展记录?真:假//假
const withIndex:Record={bar:'bar'}//缺少a,b
更新

/**
*记录的解释
*这意味着对象应该具有a和b键
*/
类型CustomRecord=记录
const allowedRecord:CustomRecord={
a:‘1’,
b:‘2’
}//好的
常量allowedRecord2:CustomRecord={
a:‘1’,
}//错误,因为没有b
常量allowedRecord3:CustomRecord={
b:‘1’,
}//错误,因为没有
/**
*您无法对索引类型执行相同的操作
*/
键入TypeIndexedWIthExplicitKeys={
[p:string | number]:字符串
}
带有明确键的接口索引{
[p:'a'|'b']:字符串
}
常量x:InterfaceIndexedWIthExplicitKeys={2:'s'}//没有错误,但是。。。。我认为会有错误
常量y:TypeIndexedWIthExplicitKeys={2:'s'}//没有错误,但是。。。。我认为会有错误
常量检查=():InterfaceIndexedWIthExplicitKeys=>{
返回{2:2}//没有错误,但我希望
}
键入MyRecord=Record
常量z:MyRecord={2:'2'}//错误,因为我们需要a&b
常量c:MyRecord={a:'2',b:'3'}//ok

我对Test3和Test4有点困惑。你能提供一个或多个例子来解释同样的事情吗?这对我很有帮助。。。理解“您可以在Record-Record中使用联合类型作为键,而在索引类型中不能使用联合类型:”您通过示例解释了同样的事情。@SubratoPatnaik我做了一个更新