从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还是stringlet 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就是断言参数pstring类型,从而在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的类型了,比较灵活也比较难,可能要在实际项目中用用就会比较好掌握。

时间: 2024-10-12 22:47:28

从C#到TypeScript - 高级类型的相关文章

TypeScript高级类型

交叉类型(Intersection Types) 交叉类型是将多个类型合并为一个类型. 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性. 例如,Person & Serializable & Loggable同时是Person和Serializable和Loggable. 就是说这个类型的对象同时拥有了这三种类型的成员. 我们大多是在混入(mixins)或其它不适合典型面向对象模型的地方看到交叉类型的使用. (在JavaScript里发生这种情况的场合很多

TypeScript 高级类型

一 , 交叉类型(操作符 & ): 代码 : function extend<T, U>(first: T, second: U): T & U {     let result = <T & U>{};     for (let id in first) {         (<any>result)[id] = (<any>first)[id];     }     for (let id in second) {        

013 --TypeScript之高级类型

交叉类型可以简单理解为将多个类型合并成一个类型 function extend<T, U>(first: T, second: U): T & U { let result = {} as T & U for(let id in first) { result[id] = first[id] as any } for(let id in second){ if(!result.hasOwnProperty(id)){ result[id] = second[id] as any

Typescript #2 类型概览

原始类型 Javascript原始类型也同样适用于 TypeScript的类型系统.因此,string, number,boolean也可以被用作类型注解: let num: number; let str: string; let bool: boolean; num = 123; num = 123.45; num = '123'; //Type '"123"' is not assignable to type 'number' str = '123'; str = 123; /

TS(6)-- 类型推论、类型兼容性、高级类型

2019-11-09: 学习内容:类型推论.类型兼容性.高级类型 一.类型推论:类型是在哪里如何被推断的 在有些没有明确指出类型的地方,类型推论会帮助提供类型.如:let x = 3;  变量x的类型被推断为数字. 这种推断发生在初始化变量和成员,设置默认参数值和决定函数返回值时.大多数情况下,类型推论是直截了当地. 最佳通用类型:如: let x = [0, 1, null];   两种选择:number 和 null , 计算通用类型算法会考虑所有的候选类型,并给出一个兼容所有候选类型的类型

scala一些高级类型

package com.ming.test import scala.collection.mutable.ArrayBuffer import scala.io.Source import java.awt.image.BufferedImage import javax.imageio.ImageIO import java.io.File /** * 高级类型 */ //单例类型,链式调用 class Document{ def setTitle(title:String)={this}

【Go入门教程3】基本类型 和 高级类型

基本类型 Go 有很多预定义类型,这里简单地把它们分为 基本类型 和 高级类型.Go 的基本类型并不多,而且大部分都与整数相关,如下表所示: 名 称 宽度(字节) 零 值 说 明 bool 1 false 布尔类型,其值不为真即为假.真用常量 true 表示,假由常量 false 表示 byte 1 0 字节类型,它也可以看作是一个由 8 位二进制数表示的无符号整数类型 rune 4 0 rune 类型,它是有 Go 语言定义的特有的数据类型,专用于存储 Unicode 字符.它也可以看作一个由

TypeScript入门三:TypeScript函数类型

TypeScript函数类型 TypeScript函数的参数 TypeScript函数的this与箭头函数 TypeScript函数重载 一.TypeScript函数类型 在上一篇博客中已经对声明TypeScript类型变量已经做了初步的解析,这里先回顾以下: 1 //声明函数 2 function add1(x:number,y:number):number{ 3 return x+y; 4 } 5 6 let add2 = function(x:number,y:number):number

TypeScript的类型

⒈TypeScript的类型 JavaScript语言的数据类型包括以下7种: 1.boolean(布尔),true || false 2.null,表明null值得特殊关键字,JavaScript是大小写敏感的,不要误写成Null或者NULL 3.undefined,变量未定义时的属性 4.number,表示数字,例如1.1.2等等 5.string,表示字符串,例如:“Hello World!” 6.symbol,一种数据类型(在ES6种新添加的类型),表示该实例唯一且不可改变. 7.obj