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
    }
  }
  return result
 }
 //为了编译通过,我们让上述的first[id],second[id]断言成了any

 class Person {
   constructor(public name: string){

   }
 }

 interface loggable {
   log(): void
 }

 class ConsoleLogger implements loggable {
  log(){

  }
 }

 var jim = extend(new Person(‘jim‘), new ConsoleLogger())
 //通过extend函数使两个class扩展到一起,称为交叉类型
 jim.name
 jim.log()

编译后

function extend(first, second) {
    var result = {};
    for (var id in first) {
        result[id] = first[id];
    }
    for (var id in second) {
        if (!result.hasOwnProperty(id)) {
            result[id] = second[id];
        }
    }
    return result;
}
//为了编译通过,我们让上述的first[id],second[id]断言成了any
var Person = /** @class */ (function () {
    function Person(name) {
        this.name = name;
    }
    return Person;
}());
var ConsoleLogger = /** @class */ (function () {
    function ConsoleLogger() {
    }
    ConsoleLogger.prototype.log = function () {
    };
    return ConsoleLogger;
}());
var jim = extend(new Person(‘jim‘), new ConsoleLogger());
//通过extend函数使两个class扩展到一起,称为交叉类型
jim.name;
jim.log();

联合类型

function padLeft(value: string, padding: any/*string | number */) {
  if(typeof padding === ‘number‘){
    return Array(padding + 1).join(‘ ‘) + value
  }
  if(typeof padding === ‘string‘) {
    return padding + value
  }
  throw new Error(`Expected string or number got ${padding}`)
}

console.log(padLeft(‘Hello world‘, 5))//     Hello world
console.log(padLeft(‘Hello world‘, ‘123‘))//123Hello world
//console.log(padLeft(‘Hello world‘, true))//这样写也不会报错,因为padding是any
//什么是联合类型呢,就是如果给padding做约束,就是padding: string | number

联合类型和交叉类型的区别是什么?联合类型是几种之一,交叉类型是几种类型之和

interface Bird {
  fly()

  layEggs()
}

interface Fish {
  swim()

  layEggs()
}

function getSmallPet(): Fish | Bird {
  return //...
}

let pet = getSmallPet()
pet.layEggs()
//pet.swim()//报错,因为上面声明了是联合类型
//getSmallPet只能是Fish或者Bird
//所以只能调用它们共有的方法

类型保护

上述例子中我们如何判断是哪个类型呢

interface Bird {
  fly()

  layEggs()
}

interface Fish {
  swim()

  layEggs()
}

function getSmallPet(): Fish | Bird {
  return //...
}

let pet = getSmallPet()

if (isFish(pet)){
  pet.swim()
} else {
  pet.fly()
}
//类型谓词的类型保护机制
function isFish(pet: Fish | Bird): pet is Fish {
 return (pet as Fish).swim !== undefined
}
function isNumber(x: any): x is number {
  return typeof x === ‘number‘
}

function isString(x: any): x is string {
  return typeof x === ‘string‘
}

function padLeft(value: string, padding: string | number){
  if (isNumber(padding)) {
    return Array(padding + 1).join(‘‘) + value
  }
  if (isString(padding)) {
    return padding + value
  }
  throw new Error(`Expected string or number, got ${padding}`)
}

typeof的类型保护机制

//typeof对基础类型提供类型保护,可以直接推断出值的类型,而不必像上例那样写
//一般 === 和 !==提供保护
//其他的可以用谓词保护
function padLeft(value: string, padding: string | number){
  if (typeof padding === ‘number‘) {
    return Array(padding + 1).join(‘‘) + value
  }
  if (typeof padding === ‘string‘) {
    return padding + value
  }
  throw new Error(`Expected string or number, got ${padding}`)

instanceof类型保护

class Bird {
  fly() {
    console.log(‘bird fly‘)
  }

  layEggs(){
    console.log(‘bird lay eggs‘)
  }
}

class Fish {
  swim(){
    console.log(‘fish swimming‘)
  }

  layEggs(){
    console.log(‘fish lay eggs‘)
  }
}

function getRandomPet(): Fish | Bird {
  return Math.random() > 0.5 ? new Bird() : new Fish()
}

let pet = getRandomPet()

if (pet instanceof Bird) {
  pet.fly()
}

if (pet instanceof Fish) {
  pet.swim()
}

null和undefined

回顾之前的代码

let s = null
s = null
let sn: string | null = ‘bar‘
sn = null

sn = undefined
//这段代码在编译时是不会出错的
//加上参数 --strictNullChecks会编译出错
function f(x: number, y?: number){
  return x + (y || 0)
}

f(1,2)
f(1)
f(1,undefined)

//f(1,null)报错
// ‘null‘ is not assignable to parameter of type ‘number | undefined‘.

在类中也是一样

class C {
  a:number
  b?:number//相当于联合类型number | undefined
}

let c = new C()
c.a = 12
c.a = undefined //报错,a为number
c.b = 13
c.b = undefined
c.b = null //报错

null的类型保护和类型断言

function broken(name: string | null ): string {
  function postfix(epither: string) {
    return name!.charAt(0) + ‘. the‘ + epither
  }
  name = name || ‘Bob‘
  return postfix(name)
}
//上述函数在编译时出错 --strictNullChecks
//ts编译器不知道name是否为null
//我们可以用类型断言方式给name加上!表示name不为null

高级类型之字符串字面量类型

type Easing = ‘ease-in‘ | ‘ease-out‘ | ‘ease-in-out‘

class UIElement {
  animate(dx: number, dy: number,easing: Easing) {
    if (easing === ‘ease-in‘) {
      //...
    } else if (easing === ‘ease-out‘) {

    }else if (easing === ‘ease-in-out‘) {

    }else {

    }
  }
}

let button = new UIElement()
button.animate(0, 0, ‘ease-in‘)
//button.animate(0, 0, null)//编译时报错
//Argument of type ‘null‘ is not assignable to parameter of type ‘Easing‘.

2019-05-30  09:53:16

原文地址:https://www.cnblogs.com/ccbest/p/10945225.html

时间: 2024-10-08 21:47:10

013 --TypeScript之高级类型的相关文章

从C#到TypeScript - 高级类型

C# vs TypeScript - 高级类型 上一篇讲了基础类型,基本上用基础类型足够开发了,不过如果要更高效的开发,还是要看下高级类型,这篇和C#共同点并不多,只是延用这个主题. 联合类型 可以从字面上进行理解:其实就是多个类型联合在一起,用|符号隔开.如: string | number, 表示希望这个类型既可以是string,又可以是number.联合类型的字段只能调用这些类型共同拥有的方法,除非类型推论系统自动判断出真正的类型. //这里sn就是一个联合类型的字段,由于类型推论推断出s

TypeScript高级类型

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

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 Type Innference(类型推断)

在这一节,我们将介绍TypeScript中的类型推断.我们将会讨论类型推断需要在何处用到以及如何推断. 基础 在TypeScript中,在几个没有明确指定类型注释的地方将会使用类型推断来提供类型信息. var x = 3; 变量"x"的值被推断为number.这种推断发生在变量或者成员初始化.设置参数默认值.决定函数返回类型的时候. 最佳公共类型 当需要从多个表达式中进行类型推断的时候,这些表达式的类型将会用来推断出一个"最佳公共类型".例如: var x = [0

TypeScript 之 基础类型

https://m.runoob.com/manual/gitbook/TypeScript/_book/doc/handbook/Basic%20Types.html TypeScript 的 基础类型,包括:boolean.number.string.数组.Tuple(元组).enum(枚举).any.void.null.undefined.类型断言 2种方式定义数组: 在元素类型后面接上[] let list: number[] = [1, 2, 3]; 使用数组泛型,Array<元素类型

从零学scala(九)类型参数、高级类型

一:类型参数 泛型类 //泛型类,基本和java是一致的          class Pair[T,S](val first:T,val second:S) val pair1 = new Pair("42",42)          val pair2 = new Pair[Any,Any](42,"42") 泛型函数 //返回数组中间的值          def getMiddle[T](a:Array[T]) = a(a.length/2) def mai

Typescript 实战 --- (8)高级类型

1.交叉类型 将多个类型合并成一个类型,新的类型将具有所有类型的特性,适用于对象混用 语法: 类型1 & 类型2 & 类型3 interface CatInterface { run(): void } interface DogInterface { jump(): void } // 交叉类型具有所有类型的特性 let pet: CatInterface & DogInterface = { run() {}, jump() {} } 2.联合类型 声明的类型并不确定,可以为多