TypeScript:从记录继承值的类型,而不是所有键<&燃气轮机;接口

TypeScript:从记录继承值的类型,而不是所有键<&燃气轮机;接口,typescript,interface,record,extend,Typescript,Interface,Record,Extend,我的项目中有一个主界面,它指示扩展对象属性的值类型 为了简单起见,我们假设如下: interface Printable extends Record<PropertyKey, string> { } interface Printable extends Record<keyof Printable, string> { } 但是,不必要的副作用是它将“key”范围扩大为“anystring”,因此它不会捕获以下错误: const r: Receipt = { c

我的项目中有一个主界面,它指示扩展对象属性的
类型

为了简单起见,我们假设如下:

interface Printable extends Record<PropertyKey, string> {
}
interface Printable extends Record<keyof Printable, string> {

}
但是,不必要的副作用是它将“key”范围扩大为“any
string
”,因此它不会捕获以下错误:

const r: Receipt = { customerName: "Jack" };
console.log(r.address); // UNEXPECTED: This line DOESN'T error "for Property 'address' does not exist on type 'Receipt'.(2339)"

问题: 如何从超级界面中获得“强制值类型””的好处,而不需要“加宽键范围”



另外,这与我想要一个没有对象或其实例化开销的接口的意义不同。请停止重复报告。:)

我认为至少现在是不可能的,因为你必须这样做:

interface Printable extends Record<PropertyKey, string> {
}
interface Printable extends Record<keyof Printable, string> {

}

我认为至少现在是不可能的,因为你必须这样做:

interface Printable extends Record<PropertyKey, string> {
}
interface Printable extends Record<keyof Printable, string> {

}

可以基于创建实用程序类型来验证输入类型值:

type Printable<T extends Record<PropertyKey, string>> = T;

type Receipt = Printable<{
    customerName: string;
    // customerId: number; // Expect error
}>

const r: Receipt = { customerName: "Jack" };
console.log(r.address); // Property 'address' does not exist on type '{ customerName: string; }'.
可打印类型=T;
类型收据=可打印
const r:Receipt={客户名称:“Jack”};
console.log(r.address);//类型{customerName:string;}上不存在属性“address”。

您可以基于创建实用程序类型来验证输入类型值:

type Printable<T extends Record<PropertyKey, string>> = T;

type Receipt = Printable<{
    customerName: string;
    // customerId: number; // Expect error
}>

const r: Receipt = { customerName: "Jack" };
console.log(r.address); // Property 'address' does not exist on type '{ customerName: string; }'.
可打印类型=T;
类型收据=可打印
const r:Receipt={客户名称:“Jack”};
console.log(r.address);//类型{customerName:string;}上不存在属性“address”。

这是否回答了您的问题@实际上没有,但是非常接近。最大的区别是,在那里,您需要在“对象创建/实例化”时对每个对象实例执行一些异常操作。这里,我不想那样。我希望魔法发生在“接口”创建时,所以对象实例化是正常的。我这样做的原因是我想在代码库中留下最少的内存,直到TS提供了一个通用的解决方案。无论如何,谢谢你。另外,Aleksey的解决方案非常接近你的解决方案(只是实例不可知论),应该对我有用。好吧,太棒了。很高兴分类了!这回答了你的问题吗@实际上没有,但是非常接近。最大的区别是,在那里,您需要在“对象创建/实例化”时对每个对象实例执行一些异常操作。这里,我不想那样。我希望魔法发生在“接口”创建时,所以对象实例化是正常的。我这样做的原因是我想在代码库中留下最少的内存,直到TS提供了一个通用的解决方案。无论如何,谢谢你。另外,Aleksey的解决方案非常接近你的解决方案(只是实例不可知论),应该对我有用。好吧,太棒了。很高兴分类了!谢谢你的回答,马赫迪。手动键入所有键名(在
StringOnly
中)对我来说是不可伸缩的。我认为Aleksey L.的解决方案更有效。谢谢你的回答,Mahdi。手动键入所有键名(在
StringOnly
中)对我来说是不可伸缩的。我认为Aleksey L.的解决方案更有效。