TypeScript 新鲜度(Freshness):更严格的对象字面量检查机制

作者:闭包旅人

时间:2026-10-25

浏览:343

TypeScript 采用结构化类型系统,通常允许具有相同属性的对象互相赋值。然而,针对对象字面量的“新鲜度”(Freshness)检查机制引入了更严格的规则。当对象字面量直接赋值或传递给函数时,若包含目标类型中不存在的属性,TypeScript 会报错。本文详细解析新鲜度的触发条件、例外情况(如类型断言和变量捕获)及其设计初衷,帮助开发者避免拼写错误并提升代码安全性。

文章目录

引言

TypeScript 采用结构化的类型系统。在对象类型检查中,如果类型 A 拥有类型 B 的所有属性,且对应属性的类型一致,那么类型 A 的实例通常可以赋值给类型 B。

type A = {
    name:string;
    age:number;
}
type B = {
    name:string
}
declare let a:A
declare let b: B
b = a

然而,存在一种例外情况,要求变量或参数必须具有完全相同的结构,这被称为“新鲜度”(Freshness),即更严格的对象字面量检查。

let b: {
    name:string
}
b ={name:'1',age:1}
/* 
  Type '{ name: string; age: number; }' is not assignable to type '{ name: string; }'.
  Object literal may only specify known properties, and 'age' does not exist in type '{ name: string; }'
*/
function freshness({name}:{name:string}){
    return 1
}
freshness({name:'du',age:1}); 
/*
  Argument of type '{ name: string; age: number; }' is not assignable to parameter of type '{ name: string; }'.
  Object literal may only specify known properties, and 'age' does not exist in type '{ name: string; }'
*/

示例代码

严格检查的潜在缺点

引入这种严格检查机制主要基于以下两个方面的考量:

第一,虽然结构化类型系统非常便捷,但它可能导致开发者误以为函数可以接收比实际所需更多的属性。

function logName(something: { name: string }) {
  console.log(something.name);
}
logName({ name: 'matt', job: 'being awesome' })

第二,在引入此功能之前,TypeScript 无法有效检测对象中的错误,尤其是在处理可选类型时。

interface TextOptions {
    alignment?: string;
    color?: string;
    padding?: number;
}
function drawText(opts: TextOptions) { ... }
// None of these were errors before
drawText({ align: 'center' }); // Oops
drawText({ colour: 'grey' }); // Oops
drawText({ pading: 32}); // Oops

例如,上述代码中的错误可能仅仅是属性名的拼写错误,但在引入新鲜度检查前,TypeScript 无法识别此类问题。

具体规则说明

  • 每个对象字面量在创建时都被视为“新鲜的”。
  • 当一个新的对象字面量被赋值给变量,或作为参数传递给非空的目标类型时,如果该字面量包含了目标类型中未定义的属性,TypeScript 将报错。
  • 然而,在类型断言中,或者当对象字面量的类型被扩大(expanded)时,这种新鲜度约束会消失。
var x: { foo: number };
x = { foo: 1, baz: 2 };  // Error, excess property `baz`
var y: { foo: number, bar?: number };
y = { foo: 1, baz: 2 };  // Error, excess or misspelled property `baz`

当新鲜的对象类型被捕获并赋值给一个变量后,后续对该变量的使用不会触发多余属性检查错误。

var x: { foo: number };
x1 = { foo: 1, baz: 2 };
x = x1;
var y: { foo: number, bar?: number };
y1 = { foo: 1, baz: 2 };
y = y1;

参考文档:jkchao.github.io/typescript-…

官方仓库:github.com/microsoft/T…

以上即为 TypeScript 新鲜度(Freshness)机制关于更严格对象字面量检查的详细内容。如需了解更多相关技术资料,请关注本站其他文章。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章