一、基础类型
string、number、boolean
let str: string = "hello"
let num: number = -9 // 可以是负数,十六进制,十进制,八进制,二进制
let bol: boolean = false
str = 90 // ts会报错:不能使用其他类型
// 使用模板字符串
let sentence: string = `${str} world`
数组
// 使用数组泛型 Array<元素类型>
let list: Array<number> = [1, 2, 3]
// 元素类型接[]
let list1: number[] = [1, 2, 3]
元组 Tuple
允许一个已知元素数量和类型的数组,各元素的类型不必相同
let x: [string, number]
x = ["hello", 10] // 元素类型需要对应
console.log(x[0].substr(1)) // OK
console.log(x[1].substr(1)) // Error, number没有substr方法
// 不能越界访问
console.log(x[4]) // error
联合类型:允许多个元素类型
let Day: string | number
Day = "一日" // ok
Day = 1 // ok
Day = false // error
枚举
enum Color {Red, Green, Blue}
let c: Color = Color.Green;
console.log(c) // 1,默认编号从0开始
// 设置枚举值
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
console.log(colorName); // 显示 "Green"
自动类型推断、any
- 自动类型推断
let notSuer = 4
notSuer = "hello" // 报错
- any:允许任何数据类型
let notSuer: any = 4
notSuer = "hello" // ok
notSuer = false // ok
notSuer.abc(); // ok,any类型不做类型检查
void
无返回值。它没有任何类型,刚好与any相反
function warnUser(): void {
console.log("This is my warning message"); // ok
}
function echo(): void {
return 9 // error
}
// 声明一个void类型的变量没有意义,因为只能为它赋予undefined和null
let unusable: void = undefined;
never
永不存在的值的类型。比如:抛出异常,或根本不会有返回值的函数表达式,或箭头函数表达式的返回值类型
// 返回never的函数必须存在无法达到的终点
function error(message: string): never {
throw new Error(message);
}
// 推断的返回值类型为never
function fail() {
return error("Something failed");
}
// 返回never的函数必须存在无法达到的终点
function infiniteLoop(): never {
while (true) {
}
}
收窄类型
function throwError(mag: string):never {
throw new Error(mag);
}
function len(x: string | undefined | null) {
if (!x) throwError("undefind argument");
x.length;
}
let x = null;
len(x);
null 和undefined
默认情况下null和undefined是所有类型的子类型。 就是说你可以把 null和undefined赋值给任何类型的变量
指定了--strictNullChecks标记,null和undefined只能赋值给void和它们各自。
let u: undefined = undefined;
let n: null = null;
二、函数
给每个参数添加类型,再为函数本身添加返回值类型
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; };
let myAdd: (baseValue: number, increment: number) => number =
function(x: number, y: number): number { return x + y; };
**// 两种写法一样
// 函数类型包含两部分:参数类型和返回值类型,为每个参数指定一个名字和类型。名字只是为了增加可读性。
// 只要参数类型匹配,那么它就是有效的函数类型,而不在乎参数名是否正确**
**// => 表示返回值类型,不要和es6的箭头函数混淆**
可选参数
function buildName(firstName: string = "", lastName?: string) {
return firstName + " " + lastName;
}
let result1 = buildName("Bob"); // ok, 第二个选填
let result2 = buildName("Bob", "Adams", "Sr."); // error, 超过两个参数
let result3 = buildName(undefined, "Adams"); // ok, 第一个不填要设置默认参数,并且传undefined
剩余参数:除了必填参数外,接受不确定的剩余参数
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
重载
// 前两次是函数定义,最后一个是函数实现
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
三、interface 接口
描述一个函数的结构
interface searchFunc{
(source: string, subString: string) :boolean
}
let mySearch: searchFunc = function(source: string, subString: string) :boolean {
return source.search(subString) !== -1
}
描述一个对象的结构
interface Person{
name: string
age: number
}
let tom: Person = {
name: "tom",
age: 25,
from: "" // error, 不能多写
}
let bob: Person = {
name: "bob", // error, 也不能少写
}
let bob: Person = {
name: "bob",
age: "25", // error, 类型不对
}
可选属性
interface Person{
name?: string
age: number
}
let bob: Person = {
age: 25, // ok, name选填
}
索引签名:可以定义额外的属性
interface Person{
name: string
age: number
[propName: string]: any
}
let bob: Person = {
name: "bob",
age: 25,
from: "china",
sex: "man"
}
四、类
定义类
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
sayName() {
return this.name
}
}
let animal = new Animal("bob")
console.log(animal.name) // bob
console.log(animal.sayName()) // bob
使用public修饰可省略定义成员
class Animal {
constructor(public name: string) {
this.name = name;
}
sayName() {
return this.name;
}
}
let animal = new Animal("bob");
console.log(animal.name); // bob
继承
class Animal {
constructor(public name: string) {
this.name = name;
}
sayName() {
return this.name;
}
}
class Cat extends Animal {
constructor(public name: string) {
super(name) // 调用父类的构造函数
}
sayHi(){
conso.log(this.name)
}
}
let cat = new Cat("bob");
console.log(cat.name); // bob
cat.sayName() // ok, 调用父类的方法
cat.sayHi() // ok, 调用自己的方法
get和set
class Animal {
constructor(public name: string) {
this.name = name;
}
get surnName() {
return this.name;
}
set surnName(val: string){
this.name = val;
}
}
let animal = new Animal("bob");
animal.surnName = "tom"
conso.log(animal.surnName) // tom
static
class Animal {
constructor(public name: string) {
this.name = name;
}
static isAnimal(a: string){
return a instanceof Animal
}
}
let a = new Animal("bob")
console.log(Animal.isAnimal(a)) // true, 是类的实例
public:默认就是public,制定成员是可见的
class Animal {
public name: string;
constructor(name: string) {
this.name = name;
}
public sayName() {
return this.name
}
}
let animal = new Animal("bob")
animal.name // ok
private:私有的,在当前类的外部不能访问
class Animal {
private name: string;
constructor(name: string) {
this.name = name; // 内部可以访问私有变量或方法
}
private sayName() {
return this.name
}
sayHi(){
return this.sayName() // 内部可以访问私有变量或方法
}
}
let animal = new Animal("bob")
animal.name // error, 私有的
animal.sayName() // error, 私有的
animal.sayHi() // ok
// 继承
class Cat extends Animal {
sayHi(){
this.sayName() // error, 子类不能访问父类的私有变量或方法
}
}
protected:受保护的,当前类内部和子类内部可以访问,不能在实例上访问
class Animal {
protected name: string;
constructor(name: string) {
this.name = name; // 内部可以访问私有变量或方法
}
protected sayName() {
return this.name
}
}
let animal = new Animal("bob")
animal.name // error, 不能在实例上访问
animal.sayName() // error, 不能在实例上反问
// 继承
class Cat extends Animal {
sayHi(){
this.sayName() // ok, 子类可以访问
}
}
let cat = new Cat()
cat.name // error, 子类实例上也不能访问
cat.sayName() // error, 子类实例上也不能访问
abstract:类中的抽象方法必须在子类中实现,
abstract class Animal {
constructor(public name: string) {
}
abstract render():void // 必须在子类中实现
sayHi(){ // 可不在子类中实现
}
}
class Cat extends Animal {
constructor() {
super('调用super'); // 子类的构造函数中必须调用 super()
}
render(){
console.log("实现")
}
}
readonly:只读的,只读属性必须在声明时或构造函数里被初始化
class Animal {
readonly name: string;
constructor(name: string) {
this.name = name;
}
}
let animal = new Animal("bob")
dad.name = "tom" **// error, name是只读的不能修改**
构造函数
class Animal {
name: string;
constructor(name: string) {
this.name = name;
}
}
let animal: Animal = new Animal("bob") /**/ 意思Animal的实例类型,是Animal**
五、泛型
- 不用泛型的列子
function fn(arg: number): number {
return arg;
}
// 或则使用any定义函数
function fn(arg: any): any {
return arg;
}
- 定义泛型
// T传入的类型是(比如:number),那么T就是number类型
function fn<T>(arg: T): T {
return arg;
}
fn<string>("myString") // 明确指定T是string
fn("myString"); // 不指定,则自动类型推断
- 泛型类
class ClaaNum<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let claaNum = new ClaaNum<number>();
claaNum.zeroValue = 0;
claaNum.add = function (x, y) {
return x + y;
};