huixisheng / huixisheng.github.com

前端开发者说,记录前端的故事
http://huixisheng.github.io/
12 stars 3 forks source link

TypeScript资料 #31

Open huixisheng opened 5 years ago

huixisheng commented 5 years ago

xcatliu/typescript-tutorial: TypeScript 入门教程

huixisheng commented 5 years ago

https://github.com/TypeStrong/ts-node

huixisheng commented 5 years ago

文档简介 · TypeScript中文网 · TypeScript——JavaScript的超集 https://ts.xcatliu.com/ TypeScript 入门教程 Introduction · TypeScript Handbook(中文版) TypeScript 3.1介绍_w3cschool

huixisheng commented 5 years ago

前端周刊第59期:选 Flow 还是 TypeScript? https://segmentfault.com/a/1190000009742532

huixisheng commented 5 years ago

官方文档 http://www.typescriptlang.org/docs/home.html

huixisheng commented 5 years ago

Triple-Slash Directives · TypeScript

三斜线指令是包含单个XML标签的单行注释。 注释的内容会做为编译器指令使用。 https://zhongsp.gitbooks.io/typescript-handbook/content/doc/handbook/Triple-Slash%20Directives.html

/// <reference path="..." />

类型别名 type

类型别名会给一个类型起个新名字。 类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。

类型别名不能被extends和implements(自己也不能extends和implements其它类型)

An interface can be named in an extends or implements clause, but a type alias for an object type literal cannot. An interface can have multiple merged declarations, but a type alias for an object type literal cannot.

类型别名 · TypeScript 入门教程 在Typescript中,类型和接口有什么区别? - 代码日志 https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.10 javascript - 在Typescript中,类型和接口有什么区别?

基础类型

原始数据类型(Primitive data types)和对象类型(Object types) number string boolean symbol null undefined

object

let isDone: boolean = false;
let decLiteral: number = 6;
let hexLiteral: number = 0xf00d;
let name: string = "bob";

let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
let x: [string, number];

enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;

let notSure: any = 4;
let list: any[] = [1, true, "free"];

function warnUser(): void {
    alert("This is my warning message");
}
let unusable: void = undefined;

let u: undefined = undefined;
let n: null = null;

// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
    throw new Error(message);
}

declare function create(o: object | null): void;

// 类型断言
let strLength: number = (<string>someValue).length;
let strLength: number = (someValue as string).length; // jsx只能使用这个
huixisheng commented 5 years ago

当用let声明一个变量,它使用的是词法作用域或块作用域。 不同于使用var声明的变量那样可以在包含它们的函数外访问,块作用域变量在包含它们的块或for循环之外是不能访问的。

let 同一个变量不能声明多次 (重定义及屏蔽)

解构

let {a, b}: {a: string, b: number} = o;

function keepWholeObject(wholeObject: { a: string, b?: number }) {
    let { a, b = 1001 } = wholeObject;
}

type C = { a: string, b?: number }
function f({ a, b }: C): void {
    // ...
}
huixisheng commented 5 years ago

接口 interface

interface LabelledValue {
  label: string;
}

function printLabel(labelledObj: LabelledValue) {
  console.log(labelledObj.label);
}

// 可选属性
interface SquareConfig {
  color?: string;
  width?: number;
}

// 只读
interface Point {
    readonly x: number;
    readonly y: number;
}

let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;

interface SquareConfig {
    color?: string;
    width?: number;
    [propName: string]: any;
}

// 函数类型
interface SearchFunc {
  (source: string, subString: string): boolean;
}

let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean {
  let result = src.search(sub);
  return result > -1;
}

// 可索引类型
let mySearch: SearchFunc;
mySearch = function(src: string, sub: string): boolean {
  let result = src.search(sub);
  return result > -1;
}

interface ReadonlyStringArray {
   // 索引只读
    readonly [index: number]: string;
}

// 类接口
interface ClockInterface {
    currentTime: Date;
    setTime(d: Date);
}

class Clock implements ClockInterface {
    currentTime: Date;
    setTime(d: Date) {
        this.currentTime = d;
    }
    constructor(h: number, m: number) { }
}

// 继承接口
interface Shape {
    color: string;
}

interface PenStroke {
    penWidth: number;
}

interface Square extends Shape, PenStroke {
    sideLength: number;
}

let square = <Square>{};
square.color = "blue";
square.sideLength = 10;
square.penWidth = 5.0;

// 混合类型
interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}

function getCounter(): Counter {
    let counter = <Counter>function (start: number) { };
    counter.interval = 123;
    counter.reset = function () { };
    return counter;
}

let c = getCounter();
c(10);
c.reset();
c.interval = 5.0;

// 接口继承类
class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

class Button extends Control implements SelectableControl {
    select() { }
}

class TextBox extends Control {
    select() { }
}

最简单判断该用readonly还是const的方法是看要把它做为变量使用还是做为一个属性。 做为变量使用的话用const,若做为属性则使用readonly。

huixisheng commented 5 years ago

继承extends 共有public 保护protected 私有private 只读readonly 静态属性static 抽象类abstract

abstract class Animal {
    abstract makeSound(): void;
    move(): void {
        console.log('roaming the earch...');
    }
}
huixisheng commented 5 years ago

函数

function add(x: number, y: number): number {
    return x + y;
}

let myAdd = function(x: number, y: number): number { return x + y; };

let myAdd: (x:number, y:number) => number =
    function(x: number, y: number): number { return x + y; };

// 可选参数
function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

function buildName(firstName: string, ...restOfName: string[]) {
  return firstName + " " + restOfName.join(" ");
}

// 重载
let suits = ["hearts", "spades", "clubs", "diamonds"];

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
    // Check to see if we're working with an object/array
    // if so, they gave us the deck and we'll pick the card
    if (typeof x == "object") {
        let pickedCard = Math.floor(Math.random() * x.length);
        return pickedCard;
    }
    // Otherwise just let them pick the card
    else if (typeof x == "number") {
        let pickedSuit = Math.floor(x / 13);
        return { suit: suits[pickedSuit], card: x % 13 };
    }
}

JavaScript里,this的值在函数被调用的时候才会指定

huixisheng commented 5 years ago

泛型 Generic

泛型允许程序员在强类型程序设计语言中编写代码时使用一些以后才指定的类型,在实例化时作为参数指明这些类型。

泛型 - 维基百科,自由的百科全书 泛型 - TypeScript 精通指南 (14) 从 JavaScript 到 TypeScript - 泛型 - 边城客栈 - SegmentFault 思否

function identity<T>(arg: T): T {
    return arg;
}

function loggingIdentity<T>(arg: T[]): T[] {
    console.log(arg.length);  // Array has a .length, so no more error
    return arg;
}
let two2 : <T>(a : T[]) => T = function (a) {
    return a[0];
}
huixisheng commented 5 years ago

枚举

enum Direction {
    Up = 1,
    Down,
    Left,
    Right
}

反向映射

huixisheng commented 5 years ago

交叉类型 Intersection Types

huixisheng commented 5 years ago
export = ;
export as namespace

Explain "export =" and "export as namespace" syntax in TypeScript - Stack Overflow

image

image

huixisheng commented 5 years ago

keyof

// Keep types the same, but make each property to be read-only.
type Readonly<T> = {
    readonly [P in keyof T]: T[P];
};

// Same property names, but make the value a promise instead of a concrete one
type Deferred<T> = {
    [P in keyof T]: Promise<T[P]>;
};

// Wrap proxies around properties of T
type Proxify<T> = {
    [P in keyof T]: { get(): T[P]; set(v: T[P]): void }
};
huixisheng commented 5 years ago

Typescript总结篇(二) | Poetry's Blog

huixisheng commented 5 years ago

declare 声明 https://www.tslang.cn/docs/handbook/declaration-files/by-example.html

huixisheng commented 5 years ago

自定义 TSLint 规则实践 - 前端 - 掘金 TSLint core rules

huixisheng commented 5 years ago

TSD ? TODO: [TypeScript]使用TSD管理TypeScript定義檔 | 攻城獅跳火圈 - 點部落 Typescript总结篇(二)_Poetry's Blog - jishuwen(技术文)

huixisheng commented 5 years ago

Typescript 文档读书笔记 - Blog of Leon Zhang

huixisheng commented 5 years ago

jkchao/typescript-book-chinese: TypeScript Deep Dive 中文版

huixisheng commented 5 years ago

React JSX | 深入理解 TypeScript