ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

typescript中高级类型之交叉类型与联合类型

2020-05-18 20:56:58  阅读:355  来源: 互联网

标签:typescript string number padding result 类型 中高级 id


交叉类型

交叉类型的表示方法为 Type1 & Type2,结果是取这两个类型的并集。这里是官网的例子,做了注释:

// 定义函数 extend,用来合并对象
function extend<T, U>(first: T, second: U): T & U {
    // result 是要返回结果,类型断言为 T & U
    let result = {} as T & U

    // 遍历 first,结果存入 result
    for(let id in first){
        // 不能将类型“T”分配给类型“T & U”,所以需使用断言
        result[id] = first[id] as any
    }

    // 遍历 second,结果存入 result
    for(let id in second){
        if(!result.hasOwnProperty(id)){
            // 不能将类型“U”分配给类型“T & U”,同样需要断言
            result[id] = second[id] as any
        }
    }

    // 返回结果,类型是 T & U
    return result
}

// 定义 Person 类,有 name 实例属性,类型为 string
class Person{
    constructor(public name: string){}
}

// 定义接口,要求有 log() 函数
interface Loggable{
    log(): void
}

// 定义 ConsoleLogger 类,它实现了接口 Loggable,有实例方法 log()
class ConsoleLogger implements Loggable{
    log(){

    }
}

// 使用 extend 方法合并两个类的实例,返回的是交叉类型,所以可以访问 name 和 log()
let jim = extend(new Person('Jim'), new ConsoleLogger())
let n = jim.name
jim.log()

例子中的结果可以看到,交叉类型取的是并集,拥有两个类型成员的所有属性。

 

联合类型

联合类型的表示方法为 Type1 | Type2,结果是这两个类型中的一个。还是以官网例子做解释:

function PadLeft(value: string, padding: any){
    // 如果是 number 类型,则在 value 前填充对用空格
    if(typeof padding === 'number'){
        return Array(padding + 1).join(' ') + value
    }
    // 如果是 string 类型,则直接拼接 value 和 padding
    if(typeof padding === 'string'){
        return padding + value
    }

    // 如果不是 string 和 number,抛出错误
    throw new Error(`Expected string or number, got '${padding}'.`)
}

PadLeft("hello world", 4) // '    hello world'

上述代码可以通过编译,能正常运行,但是有一个问题,就是 padding 的类型,当 padding 传入的既不是 number 也不是 string 时,虽然运行结果会抛出错误,但是在编译阶段不会提示问题:

padLeft("Hello world", true); // 编译阶段通过,运行时报错

要在编译阶段就可以知道问题,可以使用联合类型来替代 any 类型:

function PadLeft(value: string, padding: string | number){
    // ...
}

PadLeft("hello world", true) // error,类型“true”的参数不能赋给类型“string | number”的参数。

联合类型表示一个值可以是几种类型之一。 我们用竖线( |)分隔每个类型,所以 number | string | boolean 表示一个值可以是 number, string,或 boolean

 

需要注意的是,访问联合类型的属性时,只能访问此联合类型的所有类型里共有的属性:

let a: string | number

a.length // 类型“string | number”上不存在属性“length”。类型“number”上不存在属性“length”。

length 不存在于 number,所以编译不通过。可以看出这跟交叉类型不一样,交叉类型是可以访问所有成员的属性。

 

总结

交叉类型是多个类型合并为一个类型,可以访问所有类型的属性;联合类型是多个类型中的某一个,只能访问所有类型的共有属性。

 

标签:typescript,string,number,padding,result,类型,中高级,id
来源: https://www.cnblogs.com/wjaaron/p/12909736.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有