TypeScript 学习笔记 之 高级类型

Intersection Types 组合类型

比如 SerializableDeserializable 可以通过 & 组合出一样新的类型:Serializable & Deserializable ,也可以看作是一个匿名的扩展类型。
因为如果上面两个类型是接口类型的话,我们可以这样声明一个具名的新类型:
interface Json extends Serializable,Deserializable {}
使用实例:

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){
      if(!result.hasOwnProperty(id)){
            (<any>result)[id] = (<any>second)[id];
      }
   }
  return result;
}

Union Types 联合类型

可以通过 | 联合多个类型,创建出联合类型,例如: number|string
使用示例:

/**
 * Takes a string and adds "padding" to the left.
 * If 'padding' is a string, then 'padding' is appended to the left side.
 * If 'padding' is a number, then that number of spaces is added to the left side.
 */
function padLeft(value: string, padding: string | number) {
    // ...
}

注意: 对于联合类型的对象,我们只可以访问联合类型中各个类型存在交集的方法。要访问某一子类型的方法,需要先通过类型转换。

类型防御

  1. 用户自定义的类型防御

TS 提供了类型 kotlin 中经过检查的smartcast 的功能。
只要在类型判断函数中返回 parameterName is Type 这样的断言。即可

function isFish(pet: Fish|Bird): pet is Fish{
  return (<Fish>pet).swim !== undefined;
}
// 经过类型判断之后,pet 可以直接当某一联合类型的字类型对象使用。
if(isFish(pet)){
  pet.swim()
}else{
  pet.fly();
}
  1. 使用 typeof 的类型防御
    支持两种写法:typeof v === "typename"typeof v!== "typename"
    typename 只能是 "number","string","boolean","symbol"。如果是其他的话,TS 不会将其当作是类型防御断言。

使用 typeof 类型防御改写 padLeft

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}'.`);
}
  1. 使用 instanceof 的类型防御
    使用 instanceof 也会有智能转换的效果,instanceof 右边只能是构造函数。

类型别名

可以使用 type 创建新的类型或类型别名.

type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n:NameOrResolver):Name{
   if(typeof n == "string"){
    return n;   
  }else{
    return n(); 
  }
}

别名声明也可以使用泛型和组合类型及联合类型。

type Container<T> = { value:T};
type Tree<T> = {
  value: T;
  left : Tree<T>;
  right: Tree<T>;
}

type LinkedList<T> = T & { next: LinkedList<T> };

一些特殊用法示例:

  1. 字符串联合
    type Easing = "ease-in" | "ease-out" | "ease-in-out";
    这将限制 Easing 类型只能取上面的三个值。有点类似枚举的意思。

  2. 数值联合,类型字符串联合 。
    type DieCode = 1|2|3|4|5|6;

  3. 其他类型联合。
    type Shape = Square | Rectangle | Circle;
    现在 Shape 类型将可以使用上面联合类型的属性的交集。

Index types 索引类型

keyof T
例如:

interface Person{
  name:string,
  age:number
}

let personProps: keyof Person; // 相当于 'name' | 'age'

看一下下面的使用示例:

function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
    return o[name]; // o[name] is of type T[K]
}

T[K] 是一个动态类型。表示 T 类开中 名为 K 的属性的类型。

Mapped types 映射类型

type Keys = 'options1' | 'option2';
type Flags = { [K in Keys] : boolean };
 // 相当于 

type Flags = {
  option1: boolean;
  option2: boolean;
}

只读代理包装:

type Readonly<T> = {
   readonly [P in keyof T]: T[P];
}
type ReadonlyPerson = Readonly<Person>;

参考 :Advanced types

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容