typescript 学习笔记
typescript
编译命令
- tsc app.ts
基本数据类型
- var isBoon:boolean = false; (不给值默认 undefined)
- var num: number = 10;
- var str: string = "abc";
- var list1: number[] = [1,2,3]; (方式1)
- var list2: Array<string> = ["a","b"]; (方式2)
- 枚举类型 enum Color {red,green,blue};
- 任何类型 var notSure: any = 10;
- void类型(函数)
// 枚举 (一个星期)
enum Color {red,green,blue};
var colorName: string = Color[1]; // green
// 可自己更换下标
enum Color {red = 10,green = 20,blue};
var colorName: string = Color[10]; // red
// 获取下标
var c: Color = Color.green;
console.log(c) // => 20
// any 类型 可改变其值
var notSure: any = 10;
notSure = "hello";
notSure = false;
console.log(notSure) // false;
var list: any[] = [1,"hehe",false];
console.log(list[1]) // hehe
// void 类型 函数
function demo1(): string {} // 返回值类型 string
function dmeo2(): number{} // 返回值类型 number
function demo3(): void{} // 此函数可以有返回值也可以没有
函数类型
// 命名函数
// 可指定形参可返回值的类型
function add(x: number, y: number): number{
return x+y
}
// 匿名函数
var myAdd = function (x: number, y: string): string{
return "hello TS"
}
// 让参数有明确的意义
var myAddts: (name: string, age: number) => number = function(n: string, a: number): number {
return a;
}
// =================================================
// 可选参数
function buildName(firstName: string, lastName: string) {
return firstName + lastName;
}
var result = buildName("hhe","haha");
var result2 = buildName("hehe"); // 报错 少一个参数
var result = buildNmae("hehe", 'haha', 'dudu'); // 报错 超出参数
// ? 表示可传可不传
function buildName(firstName: string, lastName?: string){
if(lastName){
return firstName + lastName;
}else{
return firstName;
}
}
var result = buildName("hhe", "haha");
var result2 = buildName("hehe"); // 正常编译
var result3 = buildNmae("hehe", 'haha', 'dudu'); // 报错 超出参数
// =================================================
// 默认参数
function buildName(firstName: string, lastName: string = "liu"){
return firstName + lastName;
}
var result = buildName("liu"); // liuliu
var result2 = buildName("liu",'xin'); // liuxin
var result3 = buildName("liu","xin","ya"); // error
// =================================================
// 可变参数(不限参数的个数)
function demo(firstName: string, ...restOfname: string[]){
return firstName + "" + restOfname.join(" ")
}
var a = demo("a",'b','c','d');
Lambads和this关键字的使用
var people = {
name:['a','b','c'],
getName: () => {
var i = Math.floor(Math.random()*4);
return {
n: this.name[i]
}
}
}
var myName = people.getName();
alert(myName().n)
重载
function attr(name: string): string;
function attr(age: number): number;
function attr(nameorage: any): any{
if(nameorage && typeof nameorage === 'string'){
alert("姓名")
}else{
alert("年龄")
}
}
attr('hello'); // 姓名
attr(10); // 年龄
类
class Person {
name: string;
age: number;
constructor(name: string,age: number){
this.name = name;
this.age = age;
}
print(){
return this.name + this.age
}
}
var p = new Person("hehe", 18); // 必须传参
p.print();
类的继承
class Person {
name: string;
age: number;
tell() {
return this.name + ":" + this.age;
}
}
// 表示学生类也拥有Person类的name和age属性
class Student extends Person {
school: string;
tell() {
return this.name + this.age + this.school
}
}
var s = new Student();
s.name = "liu";
s.age = 800;
s.school = "hehe";
alert(s.tell());
// ========================
class Person {
name: string;
age: number;
constructor(name: string,age: number){
this.name = name;
this.age = age;
}
tell(){
return this.name + ":" + this.age;
}
}
class Student extends Person {
school: string;
constructor(school: string){
this.school = school;
super("liu", 20);
}
tell(){
return this.name + this.age + this.school
}
}
var s = new Student("hehe");
alert(s.tell()); // liu20hehe
访问修饰符
- public 默认
- private
class Person {
private name: string; // 表示私有属性 不可被继承
age: number;
print(){
return this.name + this.age
}
}
class Stu extends Person{
school: string;
print() {
return this.name + this.age + this.school
}
}
var stu1 = new Stu();
stu1.name = "liu";
stu1.age = 18;
stu1.print();
// 这样编译会报错 应为Person类的name是私有属性,stu访问不到
// ==============
class Person {
name: string;
age: number;
constructor(private name: string, age: number){
this.name = name;
this.age = age;
}
print(){
return this.name + this.age;
}
}
class Stu extends Person {
school: string;
constructor(school) {
this.school = school;
super("liu", 18)
}
print(){
return this.name + this.age + this.school;
}
}
var stu1 = new Stu("hehe");
stu1.print(); // 报错 因为Person的name是私有的
封装的实现
class Person {
private name: string;
say() {
return this.name;
}
}
var p = new Person();
p.name = "liu";
p.say(); // 报错
// 访问和设置私有属性
class Person {
private name: string;
say(){
return this.name
}
get _name(): string{
return this.name;
}
set _name(newName: string){
this.name = newName;
}
}
var p = new Person();
p._name = "haha";
alert(p.say()) // haha
static 的使用
class Person {
static name: string ;
tell() {
return this.name
};
}
var p = new Person ();
p.name = "liu"; // 报错 static不能通过实例对象来调用
p.tell();
// =======正确调用name属性====
class Person {
static name: string;
tell(){
return Person.name; // 类名.属性名
}
}
var p = new Person(); // 类名.属性名
Person.name = "liu";
p.tell();
接口
function fn(obj: {name: string}){
alert(obj.name);
}
var myObj = {name: "liu"};
fn(myObj)
// ===================
interface labelValue{
name: string;
}
function print(label: labelValue){
alert(label.name)
}
var obj = {name: "xin"};
print(obj)
接口的可选属性
interface USB{
name:string;
age:number;
}
function print(obj: USB){
console.log(obj.name)
console.log(obj.age)
}
var obj = {name: "liu", age: 10};
print(obj)
// obj里面必须有name和age
// =================
interface USB{
name?: string;
age?: number;
}
function print(obj: USB){
console.log(obj.name)
console.log(obj.age)
}
var obj = {name: "liu"};
print(obj)
// ? 代表可选 name和age都可以不写
接口的函数类型
interface PersonFun {
(name: string,age: number): boolean
}
var fn : PersonFun;
fn = function(name: string,age: number){
return false;
}
接口的数组类型
interface StringArray{
[index:number]: string;
}
var myArr: StringArray;
myArr=["a","b",'c']
接口的class类型
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 Shape{
color: string;
}
interface Square extends Shape{
sideLength: number;
}
var s = <Square>{};
s.color = "blue";
s.sideLength = 10;
// 多继承
interface Shape{
color: string;
}
interface Stroke{
width: number;
}
interface Square extends Shape,Stroke{
sideLength: number;
}
var s = <Square>{};
s.color = 'blue';
s.width = 10;
s.sideLength = 10;
// 混合类型
interface hehe {
name: string;
fn(): void;
(age: number): string;
}
var c: hehe;
c(10);.
c.fn();
接口其他
// 有时候定义一个接口,里面的属性个数是不确定的
interface A {
name: string;
age: number;
family: Array<string>;
say: () => {};
[prop: string]: any; // 就是这个东西
}
// 往TreeDataObject中再添加另外两个新属性 & 符号
resultData: (TreeDataObject & {
title: string;
origin?: TreeDataObject
})[] = []
泛型
- 有时候在定义变量的时候不确定变量的类型
function Hello<T>(arg: T): T{
return arg;
}
var output = hello<string>("hello");
alert(output)
泛型的基本应用
function Hello<T>(num: T): T{
alert(str.length); // 报错 没有自定泛型的类型 没有length
return num;
}
// ==============================
function Hello<T>(str: T[]): T[]{
alert(str.length);
return str;
}
var list:Array<string> = hello<string>(['a','b','c'])
模块
var myModule = function(vip){
// 声明私有成员
var Yvip = document.getElementById(vip);
return {
// 公开成员
add: function(t){
Yvip.innerHTML = "呵呵";
}
}
}
// =====================
module Time{
export class Test{
element: HTMLElement;
span: HTMLElement;
timer: number;
constructor(e: HTMLElement){
this.element = e;
this.element.innerHTML = "现在时间是:";
this.span = document.createElement("span");
this.element.appendChild(this.span);
this.span.innerHTML = new Date().toTimeString();
}
start(){
this.timer = setInterval(()=>{this.span.innerHTML = new Date().toTimeString()},500)
}
stop(){
clearInterval(this.timer);
}
}
}
模块之间的引用
- 三斜杠表达式
/// <reference path="./Validate" />
// 表示引入了一个同级文件夹下的Validate模块
// 引入后可用 Validate模块里面暴露出来的方法和属性
装饰器
// target 作用目标 Perple类 Object
// key 具体作用对象 'say' string
// desc 元数据描述 Objects
function test(target: any, key: string, desc: PropertyDescriptor) {
console.log(target, key, desc)
let method = desc.value;
desc.value = function (flag: boolean) {
if (flag) {
console.log('要打印了')
} else {
method()
}
}
}
class People {
name: string;
constructor(name) {
this.name = name;
}
@test
say(flag: boolean) {
console.log('是否打印')
}
}
let p = new People('liu');
p.say(true)
p.say(false)
// 装饰器工厂
function test(arg) {
return function(target, key, desc) {}
}
// 这种方式可以自己再传参(arg)
关于 reflect-metadata
-
它可通过反射机制, 获取参数类型列表
-
类型元数据使用元数据键"design:type"
-
参数类型元数据使用元数据键"design:paramtypes"
-
返回值类型元数据使用元数据键"design:returntype"
-
实现的依赖注入
import 'reflect-metadata';
let targetLists: Map<any, any[]> = new Map(); // @Injectable 装饰器作用的所有目标列表
let instanceLists: Map<any, any> = new Map(); // 实例列表
export function Injectable(_constructor: Function) {
// 通过反射机制,获取参数类型列表
let paramsTypes: Array<Function> = Reflect.getMetadata('design:paramtypes', _constructor);
targetLists.set(_constructor, paramsTypes);
}
// 这个实例用来获取依赖注入的实例
export function Ioc(injet: any){
return getIocInstance(injet);
}
function getIocInstance(inject: any) {
// 存在这个实例
if(instanceLists.has(inject)) {
return instanceLists.get(inject);
} else {
// 不存在
let relies = targetLists.get(inject) || [];
let instance = new inject(...relies.map((rely) => {
return getIocInstance(rely);
}));
instanceLists.set(inject, instance);
return instance;
}
}
@Injectable
export class Person {
constructor(
net: Unetservice,
) {}
speak() {
this.net........
}
}
let p: Person = Ioc(Person);
- @Injectable 把 Person类已经存到 targetLists 里了
- Ioc 是 先看一下 instanceLists 里面有没有 Peroson的实例, 有的话 直接拿出来
没有的话 实例化,并存到 instanceLists (方便下次ioc 直接从 instanceLists拿) 再拿出来 - 每一个类再实例化的时候, 它的constructor里面的依赖参数类 也会有和Person类一样的初始化过程
作者:liuxinya
链接:https://www.jianshu.com/p/be615c82c8a2
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。