typescript
編譯命令
- tsc app.ts
基本數(shù)據(jù)類型
- var isBoon:boolean = false; (不給值默認(rèn) 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類型(函數(shù))
// 枚舉 (一個星期)
enum Color {red,green,blue};
var colorName: string = Color[1]; // green
// 可自己更換下標(biāo)
enum Color {red = 10,green = 20,blue};
var colorName: string = Color[10]; // red
// 獲取下標(biāo)
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 類型 函數(shù)
function demo1(): string {} // 返回值類型 string
function dmeo2(): number{} // 返回值類型 number
function demo3(): void{} // 此函數(shù)可以有返回值也可以沒有
函數(shù)類型
// 命名函數(shù)
// 可指定形參可返回值的類型
function add(x: number, y: number): number{
return x+y
}
// 匿名函數(shù)
var myAdd = function (x: number, y: string): string{
return "hello TS"
}
// 讓參數(shù)有明確的意義
var myAddts: (name: string, age: number) => number = function(n: string, a: number): number {
return a;
}
// =================================================
// 可選參數(shù)
function buildName(firstName: string, lastName: string) {
return firstName + lastName;
}
var result = buildName("hhe","haha");
var result2 = buildName("hehe"); // 報錯 少一個參數(shù)
var result = buildNmae("hehe", 'haha', 'dudu'); // 報錯 超出參數(shù)
// ? 表示可傳可不傳
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'); // 報錯 超出參數(shù)
// =================================================
// 默認(rèn)參數(shù)
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
// =================================================
// 可變參數(shù)(不限參數(shù)的個數(shù))
function demo(firstName: string, ...restOfname: string[]){
return firstName + "" + restOfname.join(" ")
}
var a = demo("a",'b','c','d');
Lambads和this關(guān)鍵字的使用
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;
}
}
// 表示學(xué)生類也擁有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 默認(rèn)
- 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();
// 這樣編譯會報錯 應(yīng)為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是私有的
封裝的實現(xiàn)
class Person {
private name: string;
say() {
return this.name;
}
}
var p = new Person();
p.name = "liu";
p.say(); // 報錯
// 訪問和設(shè)置私有屬性
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不能通過實例對象來調(diào)用
p.tell();
// =======正確調(diào)用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都可以不寫
接口的函數(shù)類型
interface PersonFun {
(name: string,age: number): boolean
}
var fn : PersonFun;
fn = function(name: string,age: number){
return false;
}
接口的數(shù)組類型
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();
接口其他
// 有時候定義一個接口,里面的屬性個數(shù)是不確定的
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)
泛型的基本應(yīng)用
function Hello<T>(num: T): T{
alert(str.length); // 報錯 沒有自定泛型的類型 沒有l(wèi)ength
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 = "現(xiàn)在時間是:";
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 作用目標(biāo) Perple類 Object
// key 具體作用對象 'say' string
// desc 元數(shù)據(jù)描述 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)
關(guān)于 reflect-metadata
它可通過反射機制, 獲取參數(shù)類型列表
類型元數(shù)據(jù)使用元數(shù)據(jù)鍵"design:type"
參數(shù)類型元數(shù)據(jù)使用元數(shù)據(jù)鍵"design:paramtypes"
返回值類型元數(shù)據(jù)使用元數(shù)據(jù)鍵"design:returntype"
實現(xiàn)的依賴注入
import 'reflect-metadata';
let targetLists: Map<any, any[]> = new Map(); // @Injectable 裝飾器作用的所有目標(biāo)列表
let instanceLists: Map<any, any> = new Map(); // 實例列表
export function Injectable(_constructor: Function) {
// 通過反射機制,獲取參數(shù)類型列表
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類已經(jīng)存到 targetLists 里了
- Ioc 是 先看一下 instanceLists 里面有沒有 Peroson的實例, 有的話 直接拿出來
沒有的話 實例化,并存到 instanceLists (方便下次ioc 直接從 instanceLists拿) 再拿出來 - 每一個類再實例化的時候, 它的constructor里面的依賴參數(shù)類 也會有和Person類一樣的初始化過程
類型自動推斷題目
const test = {
aa: {aaa: 1},
bb: {bbb: 2}
}
type TestObj = typeof test;
const fun: <T extends keyof TestObj>(key: T) => TestObj[T] = key => test[key];
fun('aa'); // 自動推斷為 {aaa: number}