从C#到TypeScript - 高级类型
C# vs TypeScript - 高级类型
上一篇讲了基础类型,基本上用基础类型足够开发了,不过如果要更高效的开发,还是要看下高级类型,这篇和C#共同点并不多,只是延用这个主题。
联合类型
可以从字面上进行理解:其实就是多个类型联合在一起,用|
符号隔开。
如: string | number
, 表示希望这个类型既可以是string
,又可以是number
。
联合类型的字段只能调用这些类型共同拥有的方法,除非类型推论系统自动判断出真正的类型。
//这里sn就是一个联合类型的字段,由于类型推论推断出sn肯定是string,所以sn可以调用string的所有方法
let sn: string | number = 'string, number';
//这里就推断不出具体的类型,只能调用toString, toValue了
function snFunc(): string | number{
return 'string, number';
}
联合类型不光是可以联合基本类型,也可以是用户自定义的class, interace
等。
交叉类型
有|
就有&
,交叉类型就是用&
符号隔开,表示把多个类型合在一起,新类型包含所有类型的功能。
一些语言如Python有mixins
功能,用这个就很容易做到,主要是类似多重继承,不过个人不是用喜欢这个,明显违反了单一原则。
下面这段代码就显示了mixins
结合两个类的功能,看起来是不是有点不大合理,目前的趋势也是组合优先,用组合同样也可以做到这些。
class Person {
talk(): string {
return `一个人`;
}
}
class Dog {
bark(): string {
return '汪汪汪';
}
}
function extend<T, U>(first: T, second: U): T & U {
let result = <T & U>{};
for (let func of Object.getOwnPropertyNames(Object.getPrototypeOf(first))) {
(<any>result)[func] = (<any>first)[func];
}
for (let func of Object.getOwnPropertyNames(Object.getPrototypeOf(second))) {
(<any>result)[func] = (<any>second)[func];
}
return result;
}
let personDog = extend(new Person(), new Dog());
console.info(personDog.talk());
console.info(personDog.bark());
类型转换
C#里常用的类型转换一个是前面圆括号加类型,一个是as
。
TypeScript和C#一样,只不是圆括号改成尖括号。
let test: any = '123';
let str1: string = <string>test;
let str2: string = test as string;
类型保护
联合类型返回的是多个类型的其中一个,但是用的时候并不知道是哪个,需要一个一个判断,这显得很麻烦。
function get(): number | string{
return 'test';
}
let test = get();
var len = test.length; //编译不了,不知道test到底是number还是string
let str = '';
if((<string>test).sub){
// string
} else {
// number
}
除了通过是否有string特有的方法来判断是否是string,也可以用类似C#的typeof
来得到它的类型,而且重要的是会提供类型保护机制,
即在typeof
作用域里会知道这个变量的类型。
function get(): number | string{
return 'test';
}
let test = get();
if(typeof test === 'string'){
console.info(test.length); // 这里由于typeof确定了test类型是string,所以作用域内可以直接取length,而不用<string>转一次
}
typeof
比较是有限制的,自己创建的类返回的都是object
,这时会用到instanceof
,并且instanceof
同样会提供类型保护机制。
另外还有类型断言可以提供类似的功能,不过不如上面的来得方便。
function get(): number | string{
return 'test';
}
let test = get();
function isStr(p : number | string): p is string{
return (<string>p).sub !== 'undefined';
}
if(isStr(test)) {
console.info(test.length);
} else {
console.info(test + 1);
}
上面p is string
就是断言参数p
是string
类型,从而在isStr
后可以自动得到test
的类型,并且在else
里也知道是number
类型。
这点上比C#来得好,一般C#做法可能是用as
操作符转过来,然后判断是否为空,如果类型多操作起来也很复杂。
类型别名
类型别名即可以为现有类型取一个新名字。
type newstring = string;
let str: newstring = 'aaa';
console.info(str.length);
在C#中也可以用using strList = System.Generic.List
做个别名,不过还是不一样,C#的是可以实例化的。
TypeScript别名不是新建一个类型,而是现有类型的一个引用。
给现在类型起别名意义不大,倒是可以配合联合类型或交叉类型做成一些可读的或比较新颖的类型。
别名也支持泛型,现在就有一个用别名创建了一个Tree类型,不过也只是别名,不能实例化,只能是看的,这点不如接口实在。
class Chicken{}
class Duck{}
type Fowl = Chicken | Duck;
type Tree<T> = {
value: T;
left: Tree<T>;
right: Tree<T>;
}
字符串字面量类型
TypeScript可以让string成为一个类型,比如let strType = 'string type'
。
这个可以用在方法参数中,用来限制参数的输入。
function test(param1: 'test1' | 'test2' | 'test3'){
}
test('test'); // 编译不了,参数只能是test1, test2或test3
可辨识联合
综合上面的字符串字面量类型、联合类型、类型保护、类型别名可以创建一个可辨识联合的模式。
必须要在自定义的多个类中有相同的字段,这个字段用的是字符串字面量类型并且把这些类型联合起来。
interface Square {
kind: "square";
size: number;
}
interface Rectangle {
kind: "rectangle";
width: number;
height: number;
}
interface Circle {
kind: "circle";
radius: number;
}
type Shape = Square | Rectangle | Circle;
// 这里就可以用可辨识联合
function area(s: Shape) {
switch (s.kind) {
case "square": return s.size * s.size;
case "rectangle": return s.height * s.width;
case "circle": return Math.PI * s.radius ** 2;
}
}
类型推论
TypeScript可以根据赋值或上下文推论出变量的类型,所以有时可以不用明确标明变量或函数返回值的类型。
let x = 123; // 这里能推论出x是number,就不用写成这样: let x: number = 123;
function get(){
return [1, 2, 3];
}
let arr = get(); // 这里也能推论出arr是number[];
function get(){
return [1, '2', 3];
}
let arr = get(); // 这里能推论出arr是(number | string)[];
不过个人觉得除了一些很明显的let x = 123
之类可以不写,其他的最好还是写上类型,增加代码可读性。
以上就是TypeScript的类型了,比较灵活也比较难,可能要在实际项目中用用就会比较好掌握。
从C#到TypeScript - 高级类型的更多相关文章
- C# vs TypeScript - 高级类型
总目录 从C#到TypeScript - 类型 从C#到TypeScript - 高级类型 从C#到TypeScript - 变量 从C#到TypeScript - 接口 从C#到TypeScript ...
- Typescript高级类型与泛型难点详解
最近做的TS分享,到了高级类型这一块.通过琢磨和实验还是挖掘出了一些深层的东西,在此处做一下记录,也分享给各位热爱前端的小伙伴. 其实在学习TS之前就要明确以下几点: 1. typescrip ...
- TypeScript 高级类型
⒈交叉类型(Intersection Types) 交叉类型是将多个类型合并为一个类型. 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性. 例如, Person &a ...
- TypeScript 高级类型 接口(interface)
在代码的实现或者调用上能设定一定的限制和规范,就像契约一样.通常,我们把这种契约称为接口. TypeScript的核心原则之一是对值所具有的结构进行类型检查. 有时称为“鸭式辨型法”或“结构性子类型化 ...
- TypeScript 高级类型 类(class)
传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员来讲就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来的. 从ECMAScript ...
- TypeScript高级类型
交叉类型 将多个类型合并成一个类型,去两个类型的并集.与继承的区别是,继承可以有自己的属性,而交叉没有. interface DogInterface { run():void } interface ...
- TypeScript入门-高级类型
高级类型 交叉类型 交叉类型,就是将多个类型合并为一个新的类型,这个新的类型具有这多个类型的成员,含有这几个类型的所有特性,是他们的综合体,像是集合的并集 例子: function extend< ...
- typescript枚举,类型推论,类型兼容性,高级类型,Symbols(学习笔记非干货)
枚举部分 Enumeration part 使用枚举我们可以定义一些有名字的数字常量. 枚举通过 enum关键字来定义. Using enumerations, we can define some ...
- TypeScript 之 基础类型、高级类型
基础类型:https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/Basic%20Types.html 高级类型:https ...
随机推荐
- STL中的二分查找———lower_bound,upper_bound,binary_search
关于STL中的排序和检索,排序一般用sort函数即可,今天来整理一下检索中常用的函数——lower_bound , upper_bound 和 binary_search . STL中关于二分查找的函 ...
- C# 使用NPOI 实现Excel的简单导入导出
private void btnImport_Click(object sender, EventArgs e) { DataSet ds = new DataSet(); DataTable dt ...
- RabbitMQ核心概念篇
RabbitMQ介绍 一.RabbitMQ使用场景 RabbitMQ他是一个消息中间件,说道消息中间件[最主要的作用:信息的缓冲区]还是的从应用场景来看下: 1.系统集成与分布式系统的设计 各种子系统 ...
- javasript校验字符串【正则和其他函数】
/**javasript校验输入框值只能为数字中文英文和下划线**/function isRegex(s){ var reg=/^[a-zA-Z0-9_\u4e00-\u9fa5]+$/; if (! ...
- batの磕磕碰碰
前两天用kettle和存储过程实现了两个划小接口,然后用bat调用它们,在自己的xp系统上测试完全通过,没有任何问题. 然后很开心滴把成果打包给北京的同事他们使用.第二天他们跟我说无法取数,我马上就流 ...
- 使用CefSharp 在C#用户控件中嵌入Chrome浏览器使用方法
CEF(Chromium Embedded Framework, 嵌入式Chromium框架)是C/C++开发的库 目前 Google Chrome(Google浏览器),Chromium浏览器,Op ...
- C#设计模式(5)-建造者模式
引言 上一篇介绍了设计模式中的抽象工厂模式-C#设计模式(3)-抽象工厂模式,本篇将介绍建造者模式: 点击这里查看全部设计模式系列文章导航 建造者模式简介 建造者模式是将一个复杂对象的构建与表示分离, ...
- 49、html基础认识&常用标签(1)
从今天期我们进入前端的学习,先学习html,没有任何需要逻辑需要烧脑,只需要记忆.练习.练习.练习. 一.HTML初识 1.web服务本质 import socket def main(): sock ...
- Project 5:替换指定字符串
这个程序主要用于替换指定字符串,较为简单. #include <stdio.h> void change(char *,char *,char *); int ju(char *,char ...
- Jquery 父级元素、同级元素、子元素
prev():获取指定元素的上一个同级元素(是上一个哦). prevAll():获取指定元素的前边所有的同级元素. find():查找子元素方式 next(): 获取指定元素的下一个同级元素(注意是下 ...