` const a:number = 1
const b:string = 'b'
const c:boolean = true
const d: null = null
const e: undefined = undefined
const f:symbol = Symbol()
const g: Array = [1]
const h: number[] = [1]
const i: { foo: number } = { foo: 1 }
const j: [number, string] = [1, 'sd']
// 编译后,为双向键值对 // enum Sexs { // nan = 0, // nv = 1 // }
// 编译后,去去掉该枚举,post中的sex会变成0,nan会显示在后面的注释中 const enum Sexs { nan = 0, nv = 1 }
const post = { name: '张三', sex: Sexs.nan }
// 函数声明 function fn1 (a: number, b: number = 10): number { return a+b }
// 函数表达式 const k: (a: number, b: number) => string = function (a: number, b: number): string { return a+ b + '' }
// 任意类型 function fn2 (a: any):any { return a } // fn2('s')
// 若是定义一个变量时,未进行类型声明,typeScript会根据所附的值隐性类型推断当前变量类型,若未赋值,则推断为any,
let l = 1 // l = 'ss' fail // l = 2 success
let m // m = 'ss' success // m = 2 success
// 断言 typeScript 在某些时候,推断出来的类型不准确,此时需要断言(断定的给出更准确的答案)为其定义更加准确的类型
const temp = [100, 200, 300, 400] const n = temp.find(i => i > 0) // 推断的n类型为undefined | number const o = n as number // 这两种方式实现断言 const p = n // 该方式不能在jsx中使用,因为<>会与jsx中的<>冲突
// 接口 interface 用来约束对象类型的结构,在实际中,并没有任何意义 interface Post { name: string // 可以使用,或者; 或者不使用任何符号进行分割 age: number }
function fn3(post: Post) { console.log(post.age) console.log(post.name) }
/**
- interface 补充
- interface-1.是否有
- interface-2. 只读
- interface-3.动态属性 */
// interface-1 interface Interface1 { isHas?: number // 实际上为 isHas?: number | undefined }
// interface-2 interface Interface2 { readonly isReadonly: number }
// interface-3 interface Interface3 { [key: string]: number // key为一个代替名字,可以使用任何值, string规定属性名的类型,number为值的类型 }
// class基础使用
class Person {
public name: string
protected age: number
constructor(name: string, age: number) {
this.name = name
this.age = age
}
sayHi(arr: string): void {
console.log(name: ${this.name}, age: ${this.age}, arr: ${arr});
}
}
/**
- class 修饰符
- public 公开的
- private 私有的,外部不能访问,包括子类
- protected 受保护的 外部不能访问,子类可以访问
- ** 若构造函数是私有的,那么可以在class内部用静态方法去创建一个类 */
/**
- class readonly
- readonly 和修饰符一起使用的时候,跟在修饰符之后
- 初始化赋值readonly属性 在构造函数中/在声明的时候 二者选其一,并且初始化之后,不能在修改其值了 */
/**
- class 与 interface 的配合
- interface 可以约定 class 所具有的成员, 但是不会去限制其的实现 */
interface EatAndRun { eat (food: string): void run (addres: string): void }
class Person1 implements EatAndRun {
eat (food: string): void {
console.log(person, ${food});
}
run (addres: string): void {
console.log(person, ${addres});
}
}
class Dog1 implements EatAndRun {
eat (food: string): void {
console.log(person, ${food});
}
run (addres: string): void {
console.log(person, ${addres});
}
}
// new Person1().eat('a')
interface Eat { eat (food: string): void }
interface Run { run (addres: string): void }
class Person2 implements Eat,Run {
eat (food: string): void {
console.log(person, ${food});
}
run (addres: string): void {
console.log(person, ${addres});
}
}
class Do2 implements Eat {
eat (food: string): void {
console.log(person, ${food});
}
run (addres: string): void {
console.log(person, ${addres});
}
}
/**
- 抽象 abstract
- 抽象类 限制 类的统一行为
- 抽象类不能被new实例化
- 抽象类中的抽象方法,不用写起具体实现,但在子类中必须进行重写 */
abstract class Animal {
eat(food: string): void{
console.log('吃');
}
abstract run(add: string): void
}
class Dog extends Animal {
run(add: string): void {
console.log(add);
}
}
/**
- 泛型 用来解决定义时,不确定类型,只有在使用的时候才能确定类型,所以把类型作为泛型参数传进来进行使用。
- 基本都是用T来代表泛型参数 */
// 创建一个指定长度,指定元素的数组 // 数字 function createNumberArray (length: number, value: number): number[] { return new Array(length).fill(value) } // 字符串 function createStringArray (length: number, value: string): string[] { return new Array(length).fill(value) } // 通用,其中类型作为泛型参数传进来使用 function createArray (length: number, value: T): T[] { return new Array(length).fill(value) }
/**
- 类型声明 declare
- 在使用第三方npm依赖的时候,其中某些成员可能没有就行typescript类型声明,此时可以去安装对应依赖包的typescript声明模块
- eg: lodash, 一般typescript模块都是(@type/模块)格式,例如 @type/lodash
- 若是没有对应模块,可以利用declare 对其声明一个typescript类型
- eg: declare function a(str: string): string */`