TypeScript中的怪语法
TypeScript中的怪语法
如何处理undefined 和 null
undefined的含义是:一个变量没有初始化。
null的含义是:一个变量的值是空。
undefined 和 null 的最佳实践
- 核心思想: 避免null pointer错误。
null is bad。
要避免这个问题,我们需要做到:
用undefined,不要用null。
根据Code guidelines from Microsoft。Enable "strict" 或者 "strictNullChecks" 编译选项
在tsconfig.js中:
{
"compilerOptions": {
"strict": true,
//...
}
}
- 对于不可能是null的变量:
- 声明不能为 null 和 undefined。
- 提示编译错误:当使用一个没有初始化的变量,而这个变量不能为undefined的时候。
- 提示编译错误:当给一个不能为 null 和 undefined 的变量,赋值 null 和 undefined 的时候。
如果使用了"strictNullChecks" 编译选项,TypeScript编译器默认任何变量都不能为 undefined 和 null。除非显式声明。
var name: string; // cannot be null and undefined.
name = undefined; // Error: [ts] Type 'undefined' is not assignable to type 'string'.
name = null; // Error: [ts] Type 'null' is not assignable to type 'string'.
console.log(name); // Error: [ts] Variable 'address' is used before being assigned.
- 对于可能是undefined的变量:
- 使用显式声明
- 提示编译错误:当使用一个可能为null的变量的时候。
- 使用前,需要确定不是undefined.
var address: string | undefined; // can be undefined
class Person {
name: string; // cannot be null and undefined
address?: string; // can be undefined
}
var person : Person = {name: "Joe"};
console.log(person.address.toString()); // Error: [ts] Object is possibly 'undefined'.
if (person.address != undefined) {
console.log(person.address.toString()); //Ok. as we checked the type
}
Index Type Query - keyof
keyof 定义了一个Type, 这个Type的值来自于指定的类。
class Person {
id: number;
name: string;
birthday: Date;
}
type personPropKeys = keyof Person; // same as: type personPropKeys = "id" | "name" | "birthday"
var propKey : personPropKeys;
propKey = "id"; // OK
propKey = "name"; // OK
propKey = "age"; // Error: [ts] Type '"age"' is not assignable to type '"id" | "name" | "birthday"'.
- 用途 - 生成类的映射类型 - Mapped Types
keyof的用途是很有趣的。比如:我们希望一个ReadOnlyPerson类,这个类和类Person的属性相同,不过其中每个属性都是只读的。
TypeScript使用了keyof提供了下面的类:
// Keep types the same, but make each property to be read-only.
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};
// Same property names, but make the value a promise instead of a concrete one
type Deferred<T> = {
[P in keyof T]: Promise<T[P]>;
};
// Wrap proxies around properties of T
type Proxify<T> = {
[P in keyof T]: { get(): T[P]; set(v: T[P]): void }
};
类的参数属性 - parameter properties
class Person {
// same as to define instance fields: id, name, age
constructor(private id: number, public name: string, readonly age: number) {
}
get Id() : number {
return this.id;
}
}
var person = new Person(1, "Mary", 14);
console.log(person.name);
Type: {new(): T}
{new(): T}
的主要功能是让通用方法可以创建通用类型的对象。
但是,这个故事有点长。
- 实现方法1:通过一个方法。
// This is a generic method to create an object
function createObject<T>(name:string, creator: (arg: string) => T) : T {
return creator(name);
}
// now we have a class Person, we want to create it via function createObject
class Person {
public constructor(name: string) {
this.name = name;
}
name: string;
}
// we have to define a creator function
function createPerson(name: string): Person {
return new Person(name);
}
// at end, we can create a person
var person = createObject<Person>("Kate", createPerson);
- 实现方法2:使用构造方法。但是行不通。
但是,对象的创建者的主角是构造对象constructor。
专门定义一个creator方法也很别扭。
我们希望写成的代码是这样的,但是有一个编译错误。
没有研究过为什么这样写行不通。可能是在转义js上有一些问题。
// This is a generic method to create an object
function createObject<T>(name:string) : T {
return new T(name); // Error: [ts] 'T' only refers to a type, but is being used as a value here.
}
// now we have a class Person, we want to create it via function createObject
class Person {
public constructor(name: string) {
this.name = name;
}
name: string;
}
// at end, we can create a person
var person = createObject<Person>("Kate");
- 实现方法3:使用构造方法类型。
结合以上的方法,TypeScript提供了一个新的方式。
// This is a generic method to create an object
function createObject<T>(name:string, creator: {new(name: string): T}) : T {
return new creator(name);
}
// now we have a class Person, we want to create it via function createObject
class Person {
public constructor(name: string) {
this.name = name;
}
name: string;
}
// at end, we can create a person
var person = createObject<Person>("Kate", Person);
console.log(person);
更多的解释
{new(): T}
的类型是一个 Type,因此可以用于定义变量和参数。
new()
是描述构造函数的签名。所以在new()
中,也定义参数。比如:{new(name: string): T}
。
{new(): T}
定义了一个返回类型为 T 的构造函数的Type。
type NewObject<T> = {new(name: string): T}; // type NewPersonType = new (name: string) => Person
var newPersonType: NewObject<Person> = Person;
var person2 = new newPersonType("Joe");
// we also can write like this, as {} is the root class of object type.
type ObjectEmpty = {new(): {}}; // type ObjectEmpty = new () => {}
剩余语法
剩余参数 - Rest parameters
function restFunction(first: string, second: string, ...args: string[]): void {
console.log(args); // [ 'three', 'four' ]
}
restFunction("one", "two", "three", "four");
对象传播 - Object Spread and Rest
// shadow copy
var objCopy: any = {...obj};
console.log(objCopy); // { x: 1, y: 'name', z: 2 }
console.log(objCopy === obj); // false
// copy and change
var obj2 = {a: "age"};
objCopy = {...obj, z: "zoo"};
console.log(objCopy); // { x: 1, y: 'name', z: 'zoo' }
// merge
var obj2 = {a: "age"};
objCopy = {...obj, ...obj2};
console.log(objCopy); // { x: 1, y: 'name', z: 2, a: 'age' }
// copy and remove
let {z, ...objCopy2} = obj
console.log(objCopy2); // { x: 1, y: 'name' }
TypeScript中的怪语法的更多相关文章
- JavaScript 和 TypeScript 中的 class
对于一个前端开发者来说,很少用到 class ,因为在 JavaScript 中更多的是 函数式 编程,抬手就是一个 function,几乎不见 class 或 new 的踪影.所以 设计模式 也是大 ...
- 十分钟教你理解TypeScript中的泛型
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者.原文出处:https://blog.bitsrc.io/understanding-generics-in-t ...
- 聊聊 TypeScript 中的类型保护
聊聊 TypeScript 中的类型保护 在 TypeScript 中使用联合类型时,往往会碰到这种尴尬的情况: interface Bird { // 独有方法 fly(); // 共有方法 lay ...
- TypeScript 中命名空间与模块的理解?区别?
一.模块 TypeScript 与ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块 相反地,如果一个文件不带有顶级的import或者expo ...
- 5种在TypeScript中使用的类型保护
摘要:在本文中,回顾了TypeScript中几个最有用的类型保护,并通过几个例子来了解它们的实际应用. 本文分享自华为云社区<如何在TypeScript中使用类型保护>,作者:Ocean2 ...
- C#中的 Attribute 与 Python/TypeScript 中的装饰器是同个东西吗
前言 最近成功把「前端带师」带入C#的坑(实际是前端带师开始从cocos转unity游戏开发了) 某天,「前端带师」看到这段代码后问了个问题:[这个是装饰器]? [HttpGet] public Re ...
- 【TypeScript】如何在TypeScript中使用async/await,让你的代码更像C#。
[TypeScript]如何在TypeScript中使用async/await,让你的代码更像C#. async/await 提到这个东西,大家应该都很熟悉.最出名的可能就是C#中的,但也有其它语言也 ...
- php中一个"异类"语法: $a && $b = $c;
php中一个"异类"语法: $a && $b = $c; $a = 1;$b = 2;$c = 3;$a && $b = $c;echo & ...
- Hive中的排序语法
ORDER BY hive中的ORDER BY语句和关系数据库中的sql语法相似.他会对查询结果做全局排序,这意味着所有的数据会传送到一个Reduce任务上,这样会导致在大数量的情况下,花费大量时间. ...
随机推荐
- 【★】IT界8大恐怖预言
IT界的8大恐怖预言 本文字数:3276 建议阅读时间:你开心就好 第三次科技革命已经进入白热化阶段---信息技术革命作为其中最主要的一环已经奠定了其基本格局和趋势.OK大势已定,根据目前的形势,小编 ...
- CentOS 6.5安装部署Zabbix监控系统
CentOS 6.5安装部署Zabbix监控系统 先说一点废话,我没有用centos7做实验,讲真,centos 7我也不常用,喜欢新版本的同学其实可以尝试下,注意一点的就是centos 6.5只支持 ...
- 团队作业8——第二次项目冲刺(Beta阶段)--第四天
一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 学号 成员 贡献比 201421123001 廖婷婷 17% 201421123002 翁珊 18% 201421123004 ...
- Swing-选项卡面板JTabbedPane-入门
注:非原创,内容源自<Swing 的选项卡面板>,笔者做了少量修改. 选项卡面板是一个很常用的Swing组件,在window下,右击我的电脑,查看属性,就是一个典型的选修卡面板.当然还有最 ...
- 201521123069 《Java程序设计》 第7周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 参考资料: XMind List列表:元素以线性方式存放,允许有重复的对象. Set集:集合中的对象不按特定的方式排序,并且 ...
- 201521123049 《JAVA程序设计》 第4周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关继承的知识点. 1.2 使用常规方法总结其他上课内容. ###1.类型转换(cast):是将两种不同类型的变量进行转换,但不能随意强制转换,随意强制 ...
- 201521123050《Java程序设计》第1周学习总结
1. 本周学习总结 java至今已经不仅是个程序语言,也代表了解决问题的平台,更代表原厂,各个厂商,社群,开发者与用户沟通的成果.若以程序语言来看待java,正如冰山一角,如此便看不到java身为程序 ...
- Java-Properties用法-入门
对于应用程序的配置,通常的做法是将其保存在独立的配置文件中,程序启动时加载,修改时保存.Java中Properties类就提供了这样一种机制,配置项以Key-Value的数据结构存储在文本文件中,扩展 ...
- 201521044091 《Java程序设计》第11周学习总结
1. 本章学习总结 2. 书面作业 Q1.1.互斥访问与同步访问完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synchronized修饰方法实现互斥同步访问,还有什么办法实现互斥同 ...
- sed命令基础2
我在sed命令基础里面说了一下sed的基础用法,sed还有一些高级用法,由于我也是在学习中,写的博客可能会有想不到的地方,有问题希望大家指出. sed的高级用法主要在于两个空间的使用,模式空间和保持空 ...