在TypeScript中检查文字对象类型的更简单方法

在TypeScript中检查文字对象类型的更简单方法,typescript,object-literal,Typescript,Object Literal,我想对象。为已知类型的对象分配,一组来自对象文本的属性,这些属性应该是相同类型的。在TypeScript中有没有一种更简洁的方法来实现这一点,而不必像本文中所建议的那样调用标识函数或创建单独的变量 type Person={ 第一:字符串; 最后?:字符串; } //Overkill,实际生成调用函数的代码 函数检查(值:T):T{返回值;} 康斯特·杜德:人={ 第一个:'迈克', }; assign(dude,检查({/如果你用Object.assign来处理dude,为什么dude是常量

我想
对象。为已知类型的对象分配
,一组来自对象文本的属性,这些属性应该是相同类型的。在TypeScript中有没有一种更简洁的方法来实现这一点,而不必像本文中所建议的那样调用标识函数或创建单独的变量

type Person={
第一:字符串;
最后?:字符串;
}
//Overkill,实际生成调用函数的代码
函数检查(值:T):T{返回值;}
康斯特·杜德:人={
第一个:'迈克',
};

assign(dude,检查({/如果你用Object.assign来处理dude,为什么dude是常量

通常,如果你试图分配任何不是“人”的东西给dude,你会得到一个错误,例如

type Person = {
  first?: string;
  last?: string;
}

let dude: Person = {
  first: 'Mike',
};

dude = {  
   last: 'Johnson',
   age: 27
} // Error: Not assignable to type Person

这将检查分配,如果您想分配给常数,还会显示一个错误。

如果您使用Object.assign绕过dude,为什么dude是常数

通常,如果你试图分配任何不是“人”的东西给dude,你会得到一个错误,例如

type Person = {
  first?: string;
  last?: string;
}

let dude: Person = {
  first: 'Mike',
};

dude = {  
   last: 'Johnson',
   age: 27
} // Error: Not assignable to type Person
这将对赋值进行类型检查,如果您想赋值给常数,还会显示一个错误。

我想不出一个“完美”的解决方案,它可以在所有情况下工作。大多数说服编译器执行所需类型检查的机制还附带一些附加的运行时代码(比如一个新的中间变量赋值,或者调用一个标识函数),你已经说过你不想要


一个问题是TypeScript没有内联类型批注。(请参阅和进行讨论。)您希望能够要求编译器验证表达式
{…}
的类型是否为
Person
,如果无法验证,则让编译器投诉。TypeScript中最接近的运算符是
{…}作为Person
。但这会告诉编译器表达式
{…}
的类型是您想要询问的
Person


即使我们有一个内联注释操作符,也存在另一个问题:TypeScript中的对象类型不精确(有关讨论,请参阅)TypeScript中的对象类型是开放的,因为您可以在不破坏兼容性的情况下向它们添加更多属性。如果您有一个类型为
Person
的对象,那么您知道它的
第一个
最后一个
属性,但您确实不知道任何其他属性。因为
Person
没有提到
age
属性,这并不意味着类型为
Person
的对象不能具有
age
属性。很可能存在这样的接口:

interface AgedPerson extends Person {
  age: number;
}
TypeScript类型系统的性质意味着
{last:“Johnson”,age:27}
是一个有效的
AgedPerson
,即使你没有声明它是这样的(即使
AgedPerson
没有定义)。而且既然
AgedPerson
Person
的有效子类型,那么
{last:“Johnson”,age:27}
也是有效的
人员

现在,当人们使用像
{last:“Johnson”,age:27}这样的对象文字时
他们通常不打算添加这样的额外属性,因此TypeScript有一个名为的功能,它将对象文字视为完全相同的类型,并在添加未知属性时发出抱怨。此功能很有用,但很容易规避。因此,重要的是,如果您重构代码,则t
age
作为多余财产可能会消失:

const ageDude = { last: 'Johnson', age: 27 };
const personDude: Person = ageDude; // no error

也就是说,对于您给出的特定示例,我建议的解决方案是:

Object.assign<Person, Person>(dude, {
  last: 'Johnson',
  age: 27, // error
});
Object.assign(都德{
最后一句:“约翰逊”,
年龄:27,//错误
});
这里您是在调用
对象时手动指定泛型类型参数。assign
,其中第一个类型参数对应于第一个函数参数的类型,第二个类型参数对应于第二个函数参数的类型。您希望编译器将这两个参数都视为
Person
,因此您应该编写
Object.assign(…)
。然后出现预期的多余属性错误


好吧,希望能有帮助,祝你好运

我想不出一个“完美”的解决方案能在所有情况下都能起作用。大多数说服编译器执行您想要的类型检查的机制也伴随着一些添加的运行时代码(例如新的中间变量赋值,或调用标识函数),您已经说过您不想要这些代码


一个问题是TypeScript没有内联类型批注。(请参阅和进行讨论。)您希望能够要求编译器验证表达式
{…}
的类型是否为
Person
,如果无法验证,则让编译器投诉。TypeScript中最接近的运算符是
{…}作为Person
。但这会告诉编译器表达式
{…}
的类型是您想要询问的
Person


即使我们有一个内联注释操作符,也存在另一个问题:TypeScript中的对象类型不精确(有关讨论,请参阅)TypeScript中的对象类型是开放的,因为您可以在不破坏兼容性的情况下向它们添加更多属性。如果您有一个类型为
Person
的对象,那么您知道它的
第一个
最后一个
属性,但您确实不知道任何其他属性。因为
Person
没有提到
age
属性,这并不意味着类型为
Person
的对象不能具有
age
属性。很可能存在这样的接口:

interface AgedPerson extends Person {
  age: number;
}
TypeScript类型系统的性质意味着
{last:“Johnson”,age:27}
是有效的
AgedPerson
,即使您没有将其声明为s