TS
类
声明关键字
public private protected readonly static
存取器 getters/setters
get():string(){return this.name}
set(name:string):void{this.name=name};
static 静态属性
抽象类
abstract 定义抽象类和抽象方法
抽象方法只需要定义,但不需要实现。抽象方法和接口类似,都是只需要定义而不需要实现,且子类必须实现
静态部分和实例部分
在定义类的时候,ts会把类编译为:
var Person = /** @class */ (function () {
function Person() {
this.name = 'hello';
}
Person.prototype.action = function () {
};
return Person;
}());
当我们调用 new并执行了这个函数后,便会得到一个类的实例。 这个构造函数也包含了类的所有静态属性。 换个角度说,我们可以认为类具有 实例部分与 静态部分这两个部分。
实现接口的时候,检查的是实例部分,而不是静态部分
函数
function action(x: string, y: string): string {
return x + y;
}
let action: (x: string, y: string) => string = (x: string, y: string): string => {
return x + y;
}; // 完整声明 ,也可以不声明,因为ts会推断类型
请注意 ts => 和es6 =>的区别
ts =>: 代表的是制定函数的返回类型
es6 =>: 为箭头函数
默认值和可选参数
function action(x: string, y?: string, z: string = 'hello word'): string {
return x + y;
}//可选参数后面不能跟其他参数,如果跟了会报错,但是可以跟默认参数
剩余参数
function action(...x): any {
return x;
}
重载
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
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 };
}
}
和Java的重载有区别,这个需要在实现函数中自己去判断类型,为伪重载
泛型
将类型当做变量,传入,在确定数据类型
泛型函数
function action<T>(x: T): T { // T即为泛型
return x;
}
action<string>('hello');
泛型类
class A<T> {
public name: T;
}
枚举
enum 关键字
数字枚举
enum demo {'a', 'b', 'c'};
字符串枚举
enum Direction {
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT',
}
异构枚举
enum Direction {
'Down' = 0,
Up = 'UP',
}
计算的和常量成员
enum E2 { A = 1, B, C }
enum FileAccess {
Read = 1 << 1,
Write = 1 << 2,
ReadWrite = Read | Write,
G = "123".length
}
联合枚举与枚举成员的类型
任何字符串字面量(例如: "foo", "bar", "baz")
任何数字字面量(例如: 1, 100)
应用了一元 -符号的数字字面量(例如: -1, -100)
反向映射
enum D {
'Down' = 0,
Up = 'UP',
}
D[0]='Down';
D['Down']=0;
const声明
const enum A {'n', 'h'};
外部枚举
declare enum Enum {
A = 1,
B,
C = 2
}
外部枚举和非外部枚举之间有一个重要的区别,在正常的枚举里,没有初始化方法的成员被当成常数成员。 对于非常数的外部枚举而言,没有初始化方法时被当做需要经过计算的
类型推论
在未指出类型的时候,ts会根据内容来推断出该变量的类型
最佳通用类型
上下文类型
类型兼容性
ts类型是基于结构子类型
在基于名义类型的类型系统中,数据类型的兼容性或等价性是通过明确的声明和/或类型的名称来决定的。这与结构性类型系统不同,它是基于类型的组成结构,且不要求明确地声
例如:
interface Named {
name: string;
}
class Person {
name: string;
}
let p: Named;
// OK, because of structural typing
p = new Person();// 这种声明在java中会报错,因为他们是名义类型,而ts是根据子类型即内容来判断的
检查
比较对象
赋值的时候,可以不同对象赋值
class A {
public name: string;
}
class B {
public name: string;
public age: number;
}
let x: A = {
name: 'yzm',
};
let b: B = {
name: 'u',
age: 12,
};
x = b;// 不同类型赋值,必须满足一个条件,即值的类型必须包含赋值的变量的类型
比较函数
当返回值相同时
let x = (a: number) => 0;
let y = (b: number, s: string) => 0;
y = x; // OK 赋值时,值的参数必须在赋值的变量类型中全部找到(主要原因是函数可以省略参数,即第二个参数可以为undefind)
x = y; // Error 因为y有两个参数,但是x只有一个参数
// 返回值不同时
let x = () => ({name: 'Alice'});
let y = () => ({name: 'Alice', location: 'Seattle'});
x = y; // OK 变量的返回值必须为值的返回值的子类(返回值比较可以看成类比较)
y = x; // Error because x() lacks a location property
可选参数和剩余参数
在比较时,可选参数和必选参数是可以互换的
剩余参数被当做无限个可选参数
枚举和数字
枚举类型与数字类型兼容,并且数字类型与枚举类型兼容。不同枚举类型之间是不兼容的。比如,
enum Status { Ready, Waiting };
enum Color { Red, Blue, Green };
let status = Status.Ready;
status=9;// ok
status = Color.Green; //error
类比较
类与对象字面量和接口差不多,但有一点不同:类有静态部分和实例部分的类型。 比较两个类类型的对象时,只有实例的成员会被比较。 静态成员和构造函数不在比较的范围内。
类私有成员:
私有成员会影响兼容性判断。 当类的实例用来检查兼容时,如果目标类型包含一个私有成员,那么源类型必须包含来自同一个类的这个私有成员。 这允许子类赋值给父类,但是不能赋值给其它有同样类型的类。
高级类型
交叉类型
string & void
L & U & G 多个类型交叉,即该对象必需含有这个三个类型的成员
联合类型
string | void 表示几种类型之一
类型保护
类型保护:检查某对象的类型,然后根据类型不同,调用不同的方法和属性
类型谓词 谓词为 parameterName is Type这种形式
function isPet(x: Pet | Cat): x is Pet {
return (x as Pet).name !== undefined;
}
// 判断联合类型 x是否为Pet类型
null
null与 undefined是所有其它类型的一个有效值。 这也意味着,你阻止不了将它们赋值给其它类型,就算是你想要阻止这种情况也不行
但是可以阻止如下情况
// 使用 --strictNullChecks
类型别名
type Name = string;
type Name = string;
type Name<T> = { a: T };
type Name = string & number;
type Name = string | number;
接口 vs. 类型别名
接口:创建了一个新的名字,接口是可以被继承和实现的,利于扩展
类型别名:没有创建新的名字,不能被继承和实现
一般来说,如果想被继承和实现的,用接口
那如果无法用接口来描述,且需要使用联合类型或元组的时候,则使用类型别名
字符串字面量
type Name = 'string' | 'hello'; // name类型只能是这几个字符串中的一个类似枚举
const n:Name='h';//报错
数字字面量
type N = 1 | 2 | 3 | 4;
const n: N = 8;// 报错