TypeScript笔记

TypeScript笔记

var声明可以在包含它的函数,模块,命名空间或全局作用域内部任何位置被访问
let声明一个变量
词法作用域或块作用域
注意:
不能在1个作用域里多次声明let变量
我们可以在一个拥有块作用域变量被声明前获取它

function foo() {
   // okay to capture 'a'
   return a;
}
let a;

解构数组

let input = [1, 2];
let [first, second] = input;
// swap variables
[first, second] = [second, first];
function f([first, second]: [number, number]){
}
f(input);
let [first, ...rest] = [1,2,3,4];
let [first] = [1,2,3,4];
let [, second, , fourth] = [1,2,3,4];

对象解构

let o = {
    a: "foo",
    b: 12,
    c: "bar"
}
let { a, b } = o;

对象里使用…语法创建剩余变量

let { a, ...passthrough } = o;
let total = passthrough.b + passthrough.c.length;

({ a, b } = { a: "baz", b: 101 });

属性重命名
let { a: newName1, b: newName2 } = o; //这里的冒号不是指示类型的
相当于:
let newName1 = o.a;
let newName2 = o.b;
冒号指定它的类型, 需要在其后写上完整的模式
let {a, b}: {a: string, b: number} = o;

函数声明
解构也能用于函数声明
type C = { a: string, b?: number }
function f({ a, b }: C): void {
}

展开
展开操作符正与解构相反
数组展开: 一个数组展开为另一个数组
let first = [1, 2];
let second = [3, 4];
let bothPlus = [0, …first, …second, 5];
对象展开: 展开对象后面的属性会覆盖前面的属性,
将一个对象展开为另一个对象

let defaults = { food: "spicy", price: "$$", ambiance: "noisy" };
let search = { ...defaults, food: "rich" };
search的值为{ food: "rich", price: "$$", ambiance: "noisy" }

展开一个对象实例时,你会丢失其方法
class C {
p = 12;
m() {
}
}
let c = new C();
let clone = { …c };
clone.p; // ok
clone.m(); // error!
var声明一个变量
var作用域或函数作用域

类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以
interface SquareConfig {
color?: string; //?符号 – 可选属性
width?: number;
}
interface Point {
readonly x: number; //指定只读属性
readonly y: number;
}

(变量使用的话用 const,属性则使用readonly)

let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray = a; //数组创建后再也不能被修改
ro[0] = 12; // error!
ro.push(5); // error!
ro.length = 100; // error!
a = ro; // error!

对象字面量会被特殊对待而且会经过 额外属性检查
可使用类型断言绕开这些检查
interface SquareConfig {
color?: string;
width?: number;
}
let mySquare = createSquare({ width: 100, opacity: 0.5 }
as SquareConfig);

最佳的方式是能够添加一个字符串索引签名
interface SquareConfig {
color?: string;
width?: number;
[propName: string]: any;
}

将这个对象赋值给一个另一个变量
let squareOptions = { colour: “red”, width: 100 };
let mySquare = createSquare(squareOptions);

函数类型
使用接口表示函数类型,我们需要给接口定义一个调用签名。
它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型
interface SearchFunc {
(source: string, subString: string): boolean;
}
函数的参数会逐个进行检查,要求对应位置上的参数类型是兼容的
(不指定类型,Typescript的类型系统会推断出参数类型)

可索引的类型
两种索引签名:字符串和数字。 可以同时使用两种类型的索引
但是数字索引的返回值必须是字符串索引返回值类型的子类型
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 ClockConstructor {
new (hour: number, minute: number): ClockInterface;
}
interface ClockInterface {
tick();
}

function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface {
return new ctor(hour, minute);
}

扩展接口
和类一样,接口也可以相互扩展。
这让我们能够从一个接口里复制成员到另一个接口里,
可以更灵活地将接口分割到可重用的模块里
interface Shape {
color: string;
}
interface Square extends Shape {
sideLength: number;
}
let square = {};
square.color = “blue”;
square.sideLength = 10;

泛型函数

let output = identity<string>("myString"); //类型变量T, 指定了T是string类型
let output = identity("myString");   //类型推论
function identity<T>(arg: T): T {
    return arg;
}
let myIdentity: <T>(arg: T) => T = identity;
//使用带有调用签名的对象字面量来定义泛型函数
function identity<T>(arg: T): T {
    return arg;
}
let myIdentity: {<T>(arg: T): T} = identity;

//
interface GenericIdentityFn {
    <T>(arg: T): T;
}
function identity<T>(arg: T): T {
    return arg;
}
let myIdentity: GenericIdentityFn = identity;

interface GenericIdentityFn<T> { //接口里的其它成员也能知道这个参数的类型型
    (arg: T): T;
}
function identity<T>(arg: T): T {
    return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;

立即执行的函数表达式(IIFE)(闭包–自调用函数)

字符串
使用双引号( “)或单引号(’)表示字符串
模版字符串
可以定义多行文本和内嵌表达式。
这种字符串是被反引号包围( `),并且以${ expr }这种形式嵌入表达式

数组
元素类型 []
Array<元素类型> //数组泛型

元组 Tuple
元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同
// Declare a tuple type
let x: [string, number];
// Initialize it
x = [‘hello’, 10]; // OK

枚举
enum类型是对JavaScript标准数据类型的一个补充

any
编译时可选择地包含或移除类型检查

Object类型的变量只是允许你给它赋任意值,
但是却不能够在它上面调用任意的方法,即便它真的有这些方法

let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.

void类型的变量, 只能为它赋予undefined和null
void类型像是与any类型相反,它表示没有任何类型

let unusable: void = undefined;
默认情况下null和undefined是所有类型的子类型

never类型是任何类型的子类型,也可以赋值给任何类型;
然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。
即使 any也不可以赋值给never

类型断言
只是在编译阶段起作用
类型断言有两种形式。 其一是“尖括号”语法, as语法:

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

(TypeScript里使用JSX时,只有 as语法断言是被允许的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值