总目录

C# vs TypeScript - 高级类型

上一篇讲了基础类型,基本上用基础类型足够开发了,不过如果要更高效的开发,还是要看下高级类型,这篇和C#共同点并不多,只是延用这个主题。

联合类型

可以从字面上进行理解:其实就是多个类型联合在一起,用|符号隔开。

如: string | number, 表示希望这个类型既可以是string,又可以是number

联合类型的字段只能调用这些类型共同拥有的方法,除非类型推论系统自动判断出真正的类型。

  1. //这里sn就是一个联合类型的字段,由于类型推论推断出sn肯定是string,所以sn可以调用string的所有方法
  2. let sn: string | number = 'string, number';
  3. //这里就推断不出具体的类型,只能调用toString, toValue了
  4. function snFunc(): string | number{
  5. return 'string, number';
  6. }

联合类型不光是可以联合基本类型,也可以是用户自定义的class, interace等。

交叉类型

|就有&,交叉类型就是用&符号隔开,表示把多个类型合在一起,新类型包含所有类型的功能。

一些语言如Python有mixins功能,用这个就很容易做到,主要是类似多重继承,不过个人不是用喜欢这个,明显违反了单一原则。

下面这段代码就显示了mixins结合两个类的功能,看起来是不是有点不大合理,目前的趋势也是组合优先,用组合同样也可以做到这些。

  1. class Person {
  2. talk(): string {
  3. return `一个人`;
  4. }
  5. }
  6. class Dog {
  7. bark(): string {
  8. return '汪汪汪';
  9. }
  10. }
  11. function extend<T, U>(first: T, second: U): T & U {
  12. let result = <T & U>{};
  13. for (let func of Object.getOwnPropertyNames(Object.getPrototypeOf(first))) {
  14. (<any>result)[func] = (<any>first)[func];
  15. }
  16. for (let func of Object.getOwnPropertyNames(Object.getPrototypeOf(second))) {
  17. (<any>result)[func] = (<any>second)[func];
  18. }
  19. return result;
  20. }
  21. let personDog = extend(new Person(), new Dog());
  22. console.info(personDog.talk());
  23. console.info(personDog.bark());

类型转换

C#里常用的类型转换一个是前面圆括号加类型,一个是as

TypeScript和C#一样,只不是圆括号改成尖括号。

  1. let test: any = '123';
  2. let str1: string = <string>test;
  3. let str2: string = test as string;

类型保护

联合类型返回的是多个类型的其中一个,但是用的时候并不知道是哪个,需要一个一个判断,这显得很麻烦。

  1. function get(): number | string{
  2. return 'test';
  3. }
  4. let test = get();
  5. var len = test.length; //编译不了,不知道test到底是number还是string
  6. let str = '';
  7. if((<string>test).sub){
  8. // string
  9. } else {
  10. // number
  11. }

除了通过是否有string特有的方法来判断是否是string,也可以用类似C#的typeof来得到它的类型,而且重要的是会提供类型保护机制,

即在typeof作用域里会知道这个变量的类型。

  1. function get(): number | string{
  2. return 'test';
  3. }
  4. let test = get();
  5. if(typeof test === 'string'){
  6. console.info(test.length); // 这里由于typeof确定了test类型是string,所以作用域内可以直接取length,而不用<string>转一次
  7. }

typeof比较是有限制的,自己创建的类返回的都是object,这时会用到instanceof,并且instanceof同样会提供类型保护机制。

另外还有类型断言可以提供类似的功能,不过不如上面的来得方便。

  1. function get(): number | string{
  2. return 'test';
  3. }
  4. let test = get();
  5. function isStr(p : number | string): p is string{
  6. return (<string>p).sub !== 'undefined';
  7. }
  8. if(isStr(test)) {
  9. console.info(test.length);
  10. } else {
  11. console.info(test + 1);
  12. }

上面p is string就是断言参数pstring类型,从而在isStr后可以自动得到test的类型,并且在else里也知道是number类型。

这点上比C#来得好,一般C#做法可能是用as操作符转过来,然后判断是否为空,如果类型多操作起来也很复杂。

类型别名

类型别名即可以为现有类型取一个新名字。

  1. type newstring = string;
  2. let str: newstring = 'aaa';
  3. console.info(str.length);

在C#中也可以用using strList = System.Generic.List做个别名,不过还是不一样,C#的是可以实例化的。

TypeScript别名不是新建一个类型,而是现有类型的一个引用。

给现在类型起别名意义不大,倒是可以配合联合类型或交叉类型做成一些可读的或比较新颖的类型。

别名也支持泛型,现在就有一个用别名创建了一个Tree类型,不过也只是别名,不能实例化,只能是看的,这点不如接口实在。

  1. class Chicken{}
  2. class Duck{}
  3. type Fowl = Chicken | Duck;
  4. type Tree<T> = {
  5. value: T;
  6. left: Tree<T>;
  7. right: Tree<T>;
  8. }

字符串字面量类型

TypeScript可以让string成为一个类型,比如let strType = 'string type'

这个可以用在方法参数中,用来限制参数的输入。

  1. function test(param1: 'test1' | 'test2' | 'test3'){
  2. }
  3. test('test'); // 编译不了,参数只能是test1, test2或test3

可辨识联合

综合上面的字符串字面量类型、联合类型、类型保护、类型别名可以创建一个可辨识联合的模式。

必须要在自定义的多个类中有相同的字段,这个字段用的是字符串字面量类型并且把这些类型联合起来。

  1. interface Square {
  2. kind: "square";
  3. size: number;
  4. }
  5. interface Rectangle {
  6. kind: "rectangle";
  7. width: number;
  8. height: number;
  9. }
  10. interface Circle {
  11. kind: "circle";
  12. radius: number;
  13. }
  14. type Shape = Square | Rectangle | Circle;
  15. // 这里就可以用可辨识联合
  16. function area(s: Shape) {
  17. switch (s.kind) {
  18. case "square": return s.size * s.size;
  19. case "rectangle": return s.height * s.width;
  20. case "circle": return Math.PI * s.radius ** 2;
  21. }
  22. }

类型推论

TypeScript可以根据赋值或上下文推论出变量的类型,所以有时可以不用明确标明变量或函数返回值的类型。

  1. let x = 123; // 这里能推论出x是number,就不用写成这样: let x: number = 123;
  2. function get(){
  3. return [1, 2, 3];
  4. }
  5. let arr = get(); // 这里也能推论出arr是number[];
  6. function get(){
  7. return [1, '2', 3];
  8. }
  9. let arr = get(); // 这里能推论出arr是(number | string)[];

不过个人觉得除了一些很明显的let x = 123之类可以不写,其他的最好还是写上类型,增加代码可读性。

以上就是TypeScript的类型了,比较灵活也比较难,可能要在实际项目中用用就会比较好掌握。

C# vs TypeScript - 高级类型的更多相关文章

  1. 从C#到TypeScript - 高级类型

    C# vs TypeScript - 高级类型 上一篇讲了基础类型,基本上用基础类型足够开发了,不过如果要更高效的开发,还是要看下高级类型,这篇和C#共同点并不多,只是延用这个主题. 联合类型 可以从 ...

  2. Typescript高级类型与泛型难点详解

    最近做的TS分享,到了高级类型这一块.通过琢磨和实验还是挖掘出了一些深层的东西,在此处做一下记录,也分享给各位热爱前端的小伙伴.   其实在学习TS之前就要明确以下几点:   1. typescrip ...

  3. TypeScript 高级类型

    ⒈交叉类型(Intersection Types) 交叉类型是将多个类型合并为一个类型. 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性. 例如, Person &a ...

  4. TypeScript 高级类型 接口(interface)

    在代码的实现或者调用上能设定一定的限制和规范,就像契约一样.通常,我们把这种契约称为接口. TypeScript的核心原则之一是对值所具有的结构进行类型检查. 有时称为“鸭式辨型法”或“结构性子类型化 ...

  5. TypeScript 高级类型 类(class)

    传统的JavaScript程序使用函数和基于原型的继承来创建可重用的组件,但对于熟悉使用面向对象方式的程序员来讲就有些棘手,因为他们用的是基于类的继承并且对象是由类构建出来的. 从ECMAScript ...

  6. TypeScript高级类型

    交叉类型 将多个类型合并成一个类型,去两个类型的并集.与继承的区别是,继承可以有自己的属性,而交叉没有. interface DogInterface { run():void } interface ...

  7. TypeScript入门-高级类型

    高级类型 交叉类型 交叉类型,就是将多个类型合并为一个新的类型,这个新的类型具有这多个类型的成员,含有这几个类型的所有特性,是他们的综合体,像是集合的并集 例子: function extend< ...

  8. typescript枚举,类型推论,类型兼容性,高级类型,Symbols(学习笔记非干货)

    枚举部分 Enumeration part 使用枚举我们可以定义一些有名字的数字常量. 枚举通过 enum关键字来定义. Using enumerations, we can define some ...

  9. TypeScript 之 基础类型、高级类型

    基础类型:https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/Basic%20Types.html 高级类型:https ...

随机推荐

  1. [iOS]C语言技术视频-06-程序循环结构(for{})

    下载地址: 链接: http://pan.baidu.com/s/1dD11Zwt 密码: rke9

  2. tooltip 鼠标移动上去出现图片或文字与title大同小异

    代码如下: <script type="text/javascript" src="jquery-1.3.2.min.js"></script ...

  3. Android Camera HAL浅析

    1.Camera成像原理介绍 Camera工作流程图 Camera的成像原理可以简单概括如下: 景物(SCENE)通过镜头(LENS)生成的光学图像投射到图像传感器(Sensor)表面上,然后转为电信 ...

  4. Memcache第一篇---基础教程

    Memcache是什么 Memcache是danga.com的一个项目,最早是为 LiveJournal 服务的,目前全世界不少人使用这个缓存项目来构建自己大负载的网站,来分担数据库的压力. 它可以应 ...

  5. COM问题

    因为应用程序正在发送一个输入同步呼叫,所以无法执行传出的呼叫.

  6. mvc中怎么读取htm的文件

    @Html.Raw(File.ReadAllText(Server.MapPath("/Include/head01.htm")))

  7. (中等) POJ 3225 Help with Intervals , 线段树+集合。

    Description LogLoader, Inc. is a company specialized in providing products for analyzing logs. While ...

  8. STM32的NVIC_PriorityGroupConfig使用及优先级分组方式理解

    STM32的NVIC_PriorityGroupConfig使用及优先级分组方式理解 STM32的优先级NVIC_PriorityGroupConfig的理解及其使用 STM32中断优先级彻底讲解 S ...

  9. 理解javascript函数的重载

        javascript其实是不支持重载的,这篇文章会和java语言函数的重载对比来加深对javascript函数重载的理解.       以下我会假设读者不了解什么是重载所以会有一些很基础的概念 ...

  10. iOS开发——NSDate(待续...)

    1.获取当前系统时间,毫秒级 - (void)viewDidLoad { [super viewDidLoad]; NSString *currentTime = [self getCurrentTi ...