blog
blog copied to clipboard
TypeScript CheatSheet
TypeScript 风靡全球后不懂 TypeScript 的前端绝对不是一个好前端。TypeScript 的设计来源于大多数的静态语言,如果曾经有静态语言的开发经验,TypeScript 一整个下午就能上手。
这里记录一下 TypeScript 常用的一些语法层面的东西,方便日后查阅。
Get Start
mkdir ts-learn
npm install @types/node
npm install -g ts-node
npm install -g typescript
Tips: 为压缩页面长度 + 在
ts-node
中比较方便的执行,所有代码尽量写在了同一行。
1. Type
boolean
,number
,string
,void
,undefined
,null
const a: number = 3;
const b: number = undefined;
funtion Foo(): void {}
Tips: undefined 和 null 是所有类型的子类型。即 undefined、null 类型的变量都可以赋值其他类型。void 不可以!
2. Any
let a: any = 1;
a = 'a'
Tips: 干啥都可以,等同于 ES 时代的 JS,对他操作之后返回的也是 any。可以访问变量里面的任何属性或方法
3. Type Inference
> let y = 1;
undefined
> y = 'a'
⨯ Unable to compile TypeScript
[eval].ts (1,1): Type '"a"' is not assignable to type 'number'. (2322)
> let l = null
undefined
> l = 1
1
Tips: 在没有明确类型的时候会推到出一个类型。推到不出的时候认为是 any(如: undefined, null 这种)
4. Union Types
> let p: number | string = 1;
undefined
> p = 2
2
> p = true
⨯ Unable to compile TypeScript
[eval].ts (1,1): Type 'true' is not assignable to type 'string | number'. (2322)
> p = '2'
'2'
> let j: number | string
undefined
> j.length
⨯ Unable to compile TypeScript
[eval].ts (1,3): Property 'length' does not exist on type 'string | number'.
Property 'length' does not exist on type 'number'. (2339)
> j = '1'
'1'
> j.length
1
Tips: 在推导(Type Inference)出到底是哪个 Type 之前,访问变量的属性或方法的时候有限制,只能访问共有的属性或方法
5. Interfaces
> interface Foo { a: number, b: string, c?: boolean}
undefined
> let BBar: Foo = { a: 1, b: 2 }
⨯ Unable to compile TypeScript
[eval].ts (1,5): Type '{ a: number; b: number; }' is not assignable to type 'Foo'.
Types of property 'b' are incompatible.
Type 'number' is not assignable to type 'string'. (2322)
> interface Foo { readonly a: number, b: string, c?: boolean, [propName: string]: any}
Tips:
?
表示该属性可以不存在。但总的来说都不允许添加未定义的属性。
[propName: string]: any
表示 Foo 中可以有 key 是 string, value 是 any 的任意属性,值的注意的是这里的string
和any
必须覆盖到之前定义的确定属性和可选属性。
readonly
表示该属性只读,指第一次给对象赋值的时候而不是第一次给只读属性赋值的时候接口可以是对对象 Shape 的描述,也可以是对行为的抽象(函数输入返回(见 Fuction)或者类的抽象(见class))。
6. Array
> let g: (number|string)[] = [1, 2, 3, '4']
undefined
> let h: Array<number> = [1, 2, 3]
undefined
> let kk: any[] = [1, '1', true]
Tips: 泛型会经常被使用;Array Like Object 不是数组
7. Function
> function a(a: number, b: string, c: string = 'c', d?: string): string { return '1'}
> let r = function (a: number, b: string, c: string = 'c', d?: string): string { return '1' }
> let r: (a: number, b: string, c: string, d?: string) => string = function (a: number, b: string, c: string = 'c', d?: string): string { return '1' }
> interface R { (a: number, b: string, c: string, d?: string): string }
> let r: R = function (a: number, b: string, c: string = 'c', d?: string): string { return '1' }
> function g(a: number[], ...other: any[]): void { }
> function g(a: number): number;
> function g(a: string): string;
> function g(a: number|string) : number|string {}
>
> interface R {
(a: number, b: string, c: string, d?: string): string;
reset(): void;
num: number
}
> let r: R = function (a: number, b: string, c: string = 'c', d?: string): string {
let tep = <R>function(l: number) {}; // <R> 的写法参见 Type Assertion
tep.reset() = function() {}
tep.num = 888;
return tep;
}
Tips:
可选参数必须放在最后。
2 和 3 是函数表达式。2 中的 r 是 Type Inference 出来的,要强制的话需要写成 3。
=>
表示函数的定义,左侧是输入类型,右侧是输出类型。4 是用接口定义的,更加清晰,同时 Interface 除了定义输入返回之外还可以定义函数里面的方法或者属性。(承 5.interfaces)
6 重载,更加清晰的明确对应关系
8. Type Assertion
function g(a: number|string): void {
if(<string>a.length>0) {
console.log('isString');
} else {
console.log('is not string');
}
}
Tips: 只能断言预估好的之一,不能胡乱断
9. Declare
// zepto.d.ts
declare const $: (string) => any;
// index.ts
/// <reference path="./zepto.d.ts" />
$('#a');
Tips: 第三方库的 Types 一般使用
tnpm install @types/xx
。参考 types。
10. Standard built-in objects
> let hh: Date = new Date()
undefined
> hh
2017-11-15T16:43:24.128Z
Tips: 定义文件 参见这里。包含 ES、DOM、BOM 等,Node 使用需要安装相应的 types。
11. Type Alias
type a = (a?: string) => string
function g(m: string|a): void {}
12. String Literal Types
type specialType = 'a' | 'b' | 'c';
let a: specialType = 'a'
13. Tuple
let a: [number, string] = [1, '2']
Tips: 越界只能是已知类型的联合类型;可单独修改某个一个值;
14. Enum
enum days = { a, b, c }
enum days = { a = 1.5, b, c }
15. Class
class A extends B {
public name: string;
private age: number;
protected grade: string;
constructor(name) {
super(props);
}
}
abstract class Foo {
public name: string;
constructor(name) {
this.name = name;
}
public abstract say()
}
class Bar extends Foo {
public say() {
}
}
let bar: Bar = new Bar()
interface M {
public method1()
}
interface N {
public method2()
}
interface L extends N {
public method3();
}
class Bar extends Foo implements M, L {
public method1() {};
public method2() {};
public method3() {}
}
Tips:
public、private、protected 和 Java 中行为一致。
Abstract Class 不能被实例化,只能被其他的 class 继承,同时 abstract 中定义的 abstract 方法必须要被继承的子类实现(implements)。
Interfaces 用于不同 class 之间共有的属性或者方法。 一个 class 可以 implements 多个 interface,interface 之间也可以继承 (承上 5.interfaces)
16. Generics
function methods<T>(a: number, b: T): Array<T> {}
function swapTurple<T><U>(turple: [T, U]): [U, T] {}
interface LengthGen {
length: number
}
function testMethod<T extends LengthGen>(a: T): T {}
function testMethod<T extends U>(a: T, b: U): T {} // 保证 T的属性 U 上一定也会有
interface FooInterface<T> {
(a: number, value: T): Array<T>
}
let foo: FooInterface<any> = function method<T>(a: number, value T): Array<T> {}
Tips:
为了让类型更加准确,不全是 any
泛型也可以继承,以保证泛型中一定有某些属性或者方法(泛型约束)
泛型接口
参考资料
let foo: FooInterface<any> = function method<T>(a: number, value: T): Array<T> {}
少了个冒号
标题错了一个单词
Cheatsheet😂
@condorheroblog 嗯,我改一下 😂