typescript-学习使用ts-1

Hello World

新建 greeter.ts 并写入如下内容:程序员

function greeter(person) {
    return "Hello, " + person;
}

let user = "Jane User";

document.body.innerHTML = greeter(user);

安装编译器:typescript

npm i -g typescript

编译:shell

tsc greeter.ts

修改 greeter.ts 文件中的代码,为 greeter 函数的参数 person 加上类型声明 :stringnpm

function greeter(person: string) {
    return "Hello, " + person;
}

let user = "Jane User";

document.body.innerHTML = greeter(user);

从新编译执行。编程

让咱们继续修改:数组

function greeter(person: string) {
    return "Hello, " + person;
}

let user = [0, 1, 2];

document.body.innerHTML = greeter(user);

从新编译,你将看到以下错误:函数

error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.

接口(Interface)

interface Person {
    firstName: string;
    lastName: string;
}

function greeter(person: Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

let user = { firstName: "Jane", lastName: "User" };

document.body.innerHTML = greeter(user);

类(Class)

class Student {
    fullName: string;
    constructor(public firstName: string, public middleInitial: string, public lastName: string) {
        this.fullName = firstName + " " + middleInitial + " " + lastName;
    }
}

interface Person {
    firstName: string;
    lastName: string;
}

function greeter(person : Person) {
    return "Hello, " + person.firstName + " " + person.lastName;
}

let user = new Student("Jane", "M.", "User");

document.body.innerHTML = greeter(user);

变量声明

var

  • 做用域
  • 重复声明

let

  • 块级做用域
  • 在同一个块中不能重复声明

const

  • 声明同时必须赋值
  • 必定声明不可改变
    • 对象能够修改
  • 块级做用域

let vs const

使用最小特权原则,全部变量除了你计划去修改的都应该使用const。 基本原则就是若是一个变量不须要对它写入,那么其它使用这些代码的人也不可以写入它们,而且要思考为何会须要对这些变量从新赋值。 使用 const也可让咱们更容易的推测数据的流动。this

基本数据类型

布尔值

let isDone: boolean = false;

数字

let amount: number = 6;

字符串

  • 类型
  • 模板字符串
    • 支持换行
    • 支持内嵌表达式
  • 和 JavaScript 同样,可使用双引号,也可使用单引号,推荐单引号
let nickname: string = '张三';

还可使用模板字符串(换行 + 嵌入表达式):code

let nickname: string = `Gene`;
let age: number = 37;
let sentence: string = `Hello, my nickname is ${ nickname }.

I'll be ${ age + 1 } years old next month.`;

数组

TypeScript像JavaScript同样能够操做数组元素。 有两种方式能够定义数组。 第一种,能够在元素类型后面接上[],表示由此类型元素组成的一个数组:对象

let list: number[] = [1, 2, 3];

第二种方式是使用数组泛型,Array<元素类型>

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

元组

元组类型容许表示一个已知元素数量和类型的数组,各元素的类型没必要相同。 好比,你能够定义一对值分别为stringnumber类型的元组。

// Declare a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error

Object

  • 容许赋任意值
  • 可是不能调用任意方法,即使它真的有
let foo: Object = {
  name: 'Jack',
  age: 18
}

知道便可,用的不多,没有类型校验和语法提示

Any

有时候,咱们会想要为那些在编程阶段还不清楚类型的变量指定一个类型。 这些值可能来自于动态的内容,好比来自用户输入或第三方代码库。 这种状况下,咱们不但愿类型检查器对这些值进行检查而是直接让它们经过编译阶段的检查。 那么咱们可使用 any类型来标记这些变量:

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean

Void

void类型像是与any类型相反,它表示没有任何类型。 当一个函数没有返回值时,你一般会见到其返回值类型是 void

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

声明一个void类型的变量没有什么大用,由于你只能为它赋予undefinednull

let unusable: void = undefined;

Null 和 Undefined

void类似,它们的自己的类型用处不是很大:

// Not much else we can assign to these variables!
let u: undefined = undefined;
let n: null = null;

默认状况下nullundefined是全部类型的子类型。 就是说你能够把 nullundefined赋值给number类型的变量。

然而,当你指定了--strictNullChecks 标记,nullundefined 只能赋值给 void 和它们各自。 这能避免 不少常见的问题。许在某处你想传入一个 stringnullundefined,你可使用联合类型string | null | undefined

注意:咱们推荐尽量地使用--strictNullChecks ,由于它使你的代码更严谨,能够极大的减小出错的概率。

类型推断

有时候你会遇到这样的状况,你会比TypeScript更了解某个值的详细信息。 一般这会发生在你清楚地知道一个实体具备比它现有类型更确切的类型。

经过类型断言这种方式能够告诉编译器,“相信我,我知道本身在干什么”。 类型断言比如其它语言里的类型转换,可是不进行特殊的数据检查和解构。 它没有运行时的影响,只是在编译阶段起做用。 TypeScript会假设你,程序员,已经进行了必须的检查。

类型断言有两种形式。 其一是“尖括号”语法:

let someValue: any = "this is a string";

let strLength: number = (<string>someValue).length;

另外一个为as语法:

let someValue: any = "this is a string";

let strLength: number = (someValue as string).length;

两种形式是等价的。 至于使用哪一个大多数状况下是凭我的喜爱;然而,当你在TypeScript里使用JSX时,只有 as语法断言是被容许的。

其它

  • ReadonlyArray<T> 去除了数组的全部可变方法,确保数组建立后不再能被修改

接口

TypeScript的核心原则之一是对值所具备的结构进行类型检查。 它有时被称作“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的做用就是为这些类型命名和为你的代码或第三方代码定义契约。

基本示例

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

let myObj = { size: 10, label: "Size 10 Object" };
printLabel(myObj);

类型检查器会查看printLabel的调用。 printLabel有一个参数,并要求这个对象参数有一个名为label类型为string的属性。 须要注意的是,咱们传入的对象参数实际上会包含不少属性,可是编译器只会检查那些必需的属性是否存在,而且其类型是否匹配。 然而,有些时候TypeScript却并不会这么宽松

下面咱们重写上面的例子,此次使用接口来描述:必须包含一个label属性且类型为string

interface LabelledValue {
  label: string;
}

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

let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);

可选属性

接口里的属性不全都是必需的。 有些是只在某些条件下存在,或者根本不存在。 可选属性在应用“option bags”模式时很经常使用,即给函数传入的参数对象中只有部分属性赋值了。

interface SquareConfig {
  color?: string;
  width?: number;
}

function createSquare(config: SquareConfig): {color: string; area: number} {
  let newSquare = {color: "white", area: 100};
  if (config.color) {
    newSquare.color = config.color;
  }
  if (config.width) {
    newSquare.area = config.width * config.width;
  }
  return newSquare;
}

let mySquare = createSquare({color: "black"});

只读属性

一些对象属性只能在对象刚刚建立的时候修改其值。 你能够在属性名前用 readonly来指定只读属性:

interface Point {
    readonly x: number;
    readonly y: number;
}

你能够经过赋值一个对象字面量来构造一个Point。 赋值后, xy不再能被改变了。

let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!

readonly vs const

  • 常量使用 const
  • 对象属性使用 readonly
相关文章
相关标签/搜索