Typescript tipe freshness 更严格对象字面量检查

目录
  • 引言
    • 严格检查存在缺点
    • 具体规则而言

引言

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

但是其中有一个例外的情况,会强制 a、b 具有完全相同的结构,被称为 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; }'
*/

play

严格检查存在缺点

之所以有这样的严格检查是因为存在以下两个缺点:

1.结构化类型系统非常方便,但是它可能让你误以为某些函数接收的比他实际需要的多

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

2.在实现此功能之前 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 并不能检测出来

具体规则而言

  • 每个对象字面量都被认为是新鲜的
  • 当一个新的字面量对象被分配给一个变量或者传递给一个非空的目标类型参数时,如果对象指定了目标类型中不存在的属性,那就是一个错误
  • 在一个类型断言中,或者当一个对象字面的类型被扩大时,新鲜感就会消失
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 tipe freshness 更严格对象字面量检查的详细内容,更多关于Typescript tipe freshness对象字面量检查的资料请关注我们其它相关文章!

(0)

相关推荐

  • 如何在TypeScript中正确的遍历一个对象

    目录 JavaScript TypeScript for...in Object.keys Object.entries 思考 总结 JavaScript 在讲解用 Ts 遍历一个对象之前, 我们先说说 在 Js 中怎么实现, for...in.Object.keys, 一个简单的例子: // for...in const obj = { name: 'itsuki', address: 'hangzhou', }; for (const key in obj) { console.log(ke

  • 浅谈typescript中keyof与typeof操作符用法

    目录 一.keyof 简介 二.keyof 的作用 三.keyof 与对象的数值属性 四.keyof 与 typeof 操作符 一.keyof 简介 TypeScript 允许我们遍历某种类型的属性,并通过 keyof 操作符提取其属性的名称.keyof 操作符是在 TypeScript 2.1 版本引入的,该操作符可以用于获取某种类型的所有键,其返回类型是联合类型.下面我们来看个例子: interface Person {   name: string;   age: number;   lo

  • JS TypeScript的Map对象及联合类型实战

    目录 一.TypeScript的Map对象 1.1迭代 Map 二.TypeScript 联合类型 2.1扩展知识 2.2总结 一.TypeScript的Map对象 类型脚本映射对象. map对象保存键值对,可以记住键的原始插入顺序.任何值(对象或原始值)都可以用作键或值.Map是ES6中引入的新数据结构. Typescript使用地图类型和new关键字创建Map: let myMap = new Map(); 初始化映射,可以以数组的形式传入键值对: let myMap = new Map([

  • TypeScript数组实现栈与对象实现栈的区别详解

    目录 前言 数组实现栈 实现思路 实现代码 编写测试代码 对象实现栈 实现代码 编写测试代码 二者的区别 十进制转二进制 前言 栈作为一种数据结构,它可以应用在很多地方,当你需要经常获取刚存放进去的数据时,那么栈这种数据结构将是你的首选. 栈的实现方式一般有两种:数组实现和对象实现,这两种实现方式最终实现的功能都是一样的,但是在性能上却有着很大的差别. 本文将详细讲解这两种实现方式的差异并用TypeScript将其实现,欢迎各位感兴趣的开发者阅读本文. 数组实现栈 本文讲解的是栈用代码的实现,如

  • 基于Vue3+TypeScript的全局对象的注入和使用详解

    目录 1.Vue2的全局挂载 2.Vue3+TypeScript的全局挂载 3.Vue3+TypeScript的全局挂载的对象接口定义 刚完成一些前端项目的开发,腾出精力来总结一些前端开发的技术点,以及继续完善基于SqlSugar的开发框架循序渐进介绍的系列文章,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和使用.我们知道在Vue2中全局注入一个全局变量使用protoType的方式,很方便的就注入了,而Vue3则不能通过这种方式直接使用,而是显得复杂一些,不过全局变量的

  • 详解TypeScript映射类型和更好的字面量类型推断

    概述 TypeScript 2.1 引入了映射类型,这是对类型系统的一个强大的补充.本质上,映射类型允许w咱们通过映射属性类型从现有类型创建新类型.根据咱们指定的规则转换现有类型的每个属性.转换后的属性组成新的类型. 使用映射类型,可以捕获类型系统中类似Object.freeze()等方法的效果.冻结对象后,就不能再添加.更改或删除其中的属性.来看看如何在不使用映射类型的情况下在类型系统中对其进行编码: interface Point { x: number; y: number; } inte

  • ES6学习教程之对象字面量详解

    前言 本文主要给大家介绍了关于ES6对象字面量的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. ECMAScript6使得声明对象字面量更加简单,提供了属性简写和方法简写功能,属性名计算的新特性. function getInfo(name, age, weight) { return { // 如果属性名和属性值同名可以利用.es6的属性简写 name, // 等同于 make: make age, // 等同于 model: model weight, // 等同

  • JavaScript 对象字面量讲解

    在编程语言中,字面量是一种表示值的记法.例如,"Hello, World!" 在许多语言中都表示一个字符串字面量(string literal ),JavaScript也不例外.以下也是JavaScript字面量的例子,如5.true.false和null,它们分别表示一个整数.两个布尔值和一个空对象. JavaScript还支持对象和数组字面量,允许使用一种简洁而可读的记法来创建数组和对象.考虑以下语句,其中创建了一个包含两个属性的对象(firstName和lastName): 还可

  • 详解JS中的对象字面量

    前言 在 ES6 之前,js中的对象字面量(也称为对象初始化器)是非常基础的.可以定义两种类型的属性: 键值对{name1: value1} 获取器{ get name(){..} }和 设置器{ set name(val){..}}的计算属性值 var myObject = { myString: 'value 1', get myNumber() { return this._myNumber; }, set myNumber(value) { this._myNumber = Number

  • 浅谈js之字面量、对象字面量的访问、关键字in的用法

    一:字面量含义 字面量表示如何表达这个值,一般除去表达式,给变量赋值时,等号右边都可以认为是字面量. 字面量分为字符串字面量(string literal ).数组字面量(array literal)和 对象字面量(object literal),另外还有函数字面量(function literal). 示例: var test="hello world!"; "hello world!"就是字符串字面量,test是变量名. 二:对象字面量 对象字面量有两种访问方式

  • Javascript对象字面量的理解

    对象字面量的输出方式以及定义好处 1.对象字面量的输出方式有两种:传统的'.',以及数组方式,只不过用数组方式输出时,方括号里面要用引号括起来,如 var box = { name:'abc'; age:28 }; alert(box['name']); 给对象定义方法, A:如果用传统定义对象的方式,就需要先定义方法,然后再把这个方法名赋值给对象的一个属性,如果要调用这个方法不加括号,就是返回方法代码:如果要调用这个方法该对象属性后面加上括号,就得到方法的返回值 function objrun

  • JavaScript对象字面量和构造函数原理与用法详解

    本文实例讲述了JavaScript对象字面量和构造函数.分享给大家供大家参考,具体如下: 对象中只有两种属性:(一种比较细的分法) 属性(数据属性)比如:名字,年龄,性别,出版社,地址等信息: 方法(封装代码的属性:函数 ,在这也是一种属性). 在JS中对象的字面量和构造函数是非常的重点,其实在其他的语言中,是没有对象字面量的. 一.对象的字面量的语法: { 属性名: 属性值, 属性名: 属性值, 方法名: 你们函数 } 这个大括号括起来的整个代码块就是叫做对象. var p1 = { } ①访

  • 详解TS数字分隔符和更严格的类属性检查

    概述 TypeScript 2.4 为标识符实现了拼写纠正机制.即使咱们稍微拼错了一个变量.属性或函数名,TypeScript 在很多情况下都可以提示正确的拼写. TypeScript 2.7 支持 ECMAScript 的数字分隔符提案. 这个特性允许用户在数字之间使用下划线(_)来对数字分组(就像使用逗号和点来对数字分组那样). const worldPopulationIn2017 = 7_600_000_000; const leastSignificantByteMask = 0b11

  • 利用TypeScript从字符串字面量类型提取参数类型

    目录 正文 挑战 需要掌握的内容 字符串字面量类型 模板字面量类型和字符串字面量类型 条件类型 函数重载和通用函数 着手解决问题 分割字符串字面量类型 参数语法部分的过滤 在对象类型里做一个映射 正文 挑战 我们先来做一个ts的挑战. 你知道如何为下面的app.get方法定义TypeScript类型吗? req.params是从传入的第一个参数字符串中提取出来的. 当你想对一个类似路由的函数定义一个类型时,这显得很有用,你可以传入一个带路径模式的路由,你可以使用自定义语法格式去定义动态参数片段(

  • PHP中使用json数据格式定义字面量对象的方法

    PHPer都知道PHP是不支持字面量了,至少目前版本都不支持.比如,在JS中可以这样定义object 复制代码 代码如下: var o = { 'name' : 'qttc' , 'url' : 'www.jb51.net' }; alert(o.name); Python中定义字典,也可以这样定义: 复制代码 代码如下: o = { 'name' : 'qttc' , 'url' : 'www.jb51.net' } print o['name'] 但在PHP中这么定义object: 复制代码

随机推荐