TypeScript基礎(chǔ)語(yǔ)法

一.簡(jiǎn)介

TypeScript是JavaScript的超集,增加了數(shù)據(jù)類型, 幫助JS檢查錯(cuò)誤, 防止在大型項(xiàng)目中JS出現(xiàn)解釋錯(cuò)誤.
TypeScript最后還是會(huì)編譯成JS.

二. 類型

2.1 基本類型

let message: string = 'hello world 1';
let b: boolean = true;
let str: string | null | undefined = "|為聯(lián)合語(yǔ)法"

//數(shù)組
let arr1: Array<number> = [10, 20 ,30]
let arr2: number[] = [2, 3, 4]
let arr3: Array<number | string> = [666, "真的666"]
//參數(shù)展開運(yùn)算符
let arr5: number[] = [1, 2, 3]
let arr6: number[] = [4, 5]
arr5.push(...arr6)
console.log(arr5)//[LOG]: [1, 2, 3, 4, 5]

//元組
let tuple: [number, string] = [666, "這是元組"]
console.log(message, b, str, arr1, arr2, arr3, tuple);

//函數(shù)
let add = (x: number, y: number):number => x + y
console.log("合為"+add(1, 2))

//對(duì)象
let obj0: Object;
let obj: {x: number, y: number} = {x: 1, y: 2}
console.log("obj的值為" + obj.y)

//symbol 全局唯一引用
//symbol 類型表示一個(gè)獨(dú)一無(wú)二的標(biāo)識(shí)符。每個(gè)通過(guò) Symbol 函數(shù)創(chuàng)建的 symbol 都是唯一的瘦赫,即使它們的描述相同铺浇。
let s1: symbol = Symbol()
let s2 = Symbol()
// 創(chuàng)建一個(gè)唯一的 symbol
const mySymbol: symbol = Symbol("mySymbol");
// 創(chuàng)建另一個(gè)唯一的 symbol
const anotherSymbol: symbol = Symbol("mySymbol");
// 由于每個(gè) symbol 都是唯一的朵你,這兩個(gè) symbol 不相等
console.log(mySymbol === anotherSymbol);  // 輸出: false

//undefined
let un: undefined = undefined;
let nu: null = null;
//message = null; //報(bào)錯(cuò),因?yàn)閱?dòng)了strictNullChecks(嚴(yán)格null校驗(yàn))

//void
let noReturn = () => {}//let noReturn: () => void

//any, 變量的默認(rèn)類型為any
let aaany //let aaany: any

//nerver
let error = () => {//let error: () => never
    throw new Error("error")
}
let endless = () => {//let endless: () => never
    while(true) {
    }
}

2.2 自定義類型


//let 可變參數(shù)
let aString = "hello"
aString = "world"

//const 不可變參數(shù)
const bString = "666"
bString = "777"http://報(bào)錯(cuò)

//使用let來(lái)實(shí)現(xiàn)const, 將cString的類型定義為一個(gè)'can not changed string'這樣一個(gè)特殊類型
//等號(hào)前后要保持一致,否則會(huì)報(bào)錯(cuò)
let cString: 'can not changed string' = "can not changed string"
cString = "yes"http://報(bào)錯(cuò)

//使用特殊類型
function printText(text: string, aligment: "left" | "right" | "center") {
  console.log(text + "---" + aligment)
}
printText("label", "center")//[LOG]: "label---center" 

三. 枚舉

//數(shù)字枚舉
enum Season {
    Spring,
    Summer,
    Fall,
    Winter
}
console.log(Season.Spring)//0
console.log(Season.Fall)//2

//枚舉的原理
//轉(zhuǎn)化為JS
/*
"use strict";
var Season;
(function (Season) {
    Season[Season["Spring"] = 0] = "Spring";
    Season[Season["Summer"] = 1] = "Summer";
    Season[Season["Fall"] = 2] = "Fall";
    Season[Season["Winter"] = 3] = "Winter";
})(Season || (Season = {}));
console.log(Season.Spring); //0
console.log(Season.Fall); //2
*/


//字符串枚舉
enum Message {
    Successs = "成功",
    Fail = "失敗"
}
/*
var Message;
(function (Message) {
    Message["Successs"] = "\u6210\u529F";
    Message["Fail"] = "\u5931\u8D25";
})(Message || (Message = {}));
*/

//異構(gòu)枚舉
enum Anser{
    N,
    Y = "YES"
}
/*
var Anser;
(function (Anser) {
    Anser[Anser["N"] = 0] = "N";
    Anser["Y"] = "YES";
})(Anser || (Anser = {}));
*/


//枚舉成員
enum Char {
    //const類型俐填, 編譯時(shí)確定值
    a,          //未定義
    b = Char.a, //對(duì)其他枚舉的引用
    c = 1 + 3,  //常量

    //computed類型伶氢, 運(yùn)行時(shí)計(jì)算確定值
    d = Math.random(),
    e = "123".length
}
/*
var Char;
(function (Char) {
    //const類型澈蟆, 編譯時(shí)確定值
    Char[Char["a"] = 0] = "a";
    Char[Char["b"] = 0] = "b";
    Char[Char["c"] = 4] = "c";
    //computed類型墨辛, 運(yùn)行時(shí)計(jì)算確定值
    Char[Char["d"] = Math.random()] = "d";
    Char[Char["e"] = "123".length] = "e";
})(Char || (Char = {}));
*/

//常量枚舉, 使用const聲明; 不會(huì)被編譯進(jìn)代碼趴俘, 相當(dāng)于預(yù)編譯的宏替換
const enum Month {
    Jan,
    Fri,
    Mar
}

//枚舉類型
enum E {a, b}
enum F {a = 1, b = 2}
enum G {a = "hhh", b = "666"}

//let le: E = 3   //Type '3' is not assignable to type 'E'.
//let lf: F = 3   //Type '3' is not assignable to type 'F'.
let lg: G.a = G.a

四.類型接口

4.1 對(duì)象類型接口

interface list {
    readonly id: number,    //readonly, 只讀屬性
    name: string,
    age?: number            //?可選參數(shù)
}
interface list1 {
    readonly id: number,    //readonly, 只讀屬性
    name: string,
    age?: number            //?可選參數(shù)
}
//interface也可以繼承
interface list2  extends list, list1{
}

interface StringArray {
    [index: number]:string
}
let chars: StringArray = ["A", "B", "C"]
console.log(chars[2])//C

interface Names {
    [x: string]:string | undefined,
    [index: number]:string
}
let names: Names = {
    0: "A",
    1: "B",
    "2": "C",
    "Wow": "真的6啊"
}
console.log(names[1], names["Wow"])//"B",  "真的6啊" 

4.2 函數(shù)類型接口

//普通函數(shù)變量, 不能被繼承
let add0: (x: number, y: number) => number; //add0是一個(gè)函數(shù)類型的變量
add0 = function(x, y) {                     //給變量復(fù)制真正的函數(shù)體
    return x + y
}
console.log(add0(1, 2))// 3

//函數(shù)類型接口
interface Add1 {
    (x: number, y: number): number
}
let add1: Add1 = function (x, y){
    return x + y
}
console.log(add1(1, 5))//6

// 搞個(gè)別名
type Add2 = (x: number, y: number) => number
let add2: Add2 = (x, y) => x + y
console.log(add2(1, 9))//10

//可選參數(shù), z可以不傳睹簇, 且必須位于必選參數(shù)之后
function add5(x: number, y: number, defaultValue=6, z?: number) {
    return z ? x + y + defaultValue + z : x + y + defaultValue;
}
console.log(add5(1, 2), add5(1, 2, 3))//[LOG]: 9,  6 

五.類


//抽象類, 不能被實(shí)例化寥闪, 只能被繼承
abstract class Animal {
    eat() {
        console.log("eat")
    }
}


class Dog extends Animal{
    name: string
    static food: string = "骨頭"http://類成員,使用類名調(diào)用
    constructor(name: string) {
        super()
        this.name = name
    }
    run() {

    }
}
console.log(Dog.prototype)

let d = new Dog("汪汪汪")
d.eat();
console.log(d, d.name)
/*
[LOG]: Dog: {
  "name": "汪汪汪"
},  "汪汪汪" 
 */


//哈士奇繼承自Dog
class Husky extends Dog {
    color: string
    constructor(name: string, color: string) {
        super(name)
        this.color = color
    }
}

//哈士奇繼承自Dog-> 給參數(shù)增加public屬性太惠,可以不用在類里面定義color: string了
class Husky1 extends Dog {
    constructor(name: string, public color: string) {
        super(name)
        this.color = color
    }
}


//private   也可以使用#變量來(lái)實(shí)現(xiàn)private
//protect
// public

六.類型斷言

  • 使用as或者<>來(lái)類型斷言
  • 類型斷言會(huì)在運(yùn)行時(shí)被刪除
const m1 = document.getElementById("main") as HTMLCanvasElement
const m2 = <HTMLCanvasElement>document.getElementById("main")

七.類型縮小

7.1 使用typeof來(lái)實(shí)現(xiàn)類型守衛(wèi)

let s: string | number = "astring"
// s = 666
if (typeof s === "string") {
   console.log("字符串")
} else if (typeof s === "number") {
     console.log("數(shù)字")
}

let ret: typeof s
ret = "0.0"

7.2 真值縮小

function havePeople(count: number | string | null | undefined) {
  if (count) {
    console.log("有人")
  } else {
    console.log("沒(méi)人")
  }
}
//針對(duì)number 非0即為true
havePeople(-1)  //[LOG]: "有人" 
havePeople(0)   //[LOG]: "沒(méi)人" 
havePeople(1)   //[LOG]: "有人" 

//針對(duì)string  非空字符串為true
havePeople("")  //[LOG]: "沒(méi)人"
havePeople("h") //[LOG]: "有人"

//null和undefined都為false
havePeople(null)      //[LOG]: "沒(méi)人"
havePeople(undefined) //[LOG]: "沒(méi)人"

//或者使用一下方法 大寫B(tài)oolean或者!!, !!其實(shí)就是取反再取反
console.log(Boolean(""))  //false
console.log(Boolean("h")) //true
console.log(!!0)          //false
console.log(!!1)          //true

7.3 等值縮小

使用== === != !===來(lái)實(shí)現(xiàn)
在 TypeScript 中,== 和 === 是用于比較值的操作符疲憋,它們的行為與 JavaScript 中的相同凿渊。

  • == 是松散相等性比較,也稱為“不嚴(yán)格相等”缚柳。在比較時(shí)埃脏,會(huì)進(jìn)行類型轉(zhuǎn)換,嘗試使兩側(cè)的值類型相同秋忙,然后再進(jìn)行比較彩掐。
  • === 是嚴(yán)格相等性比較,也稱為“嚴(yán)格相等”灰追。它不進(jìn)行類型轉(zhuǎn)換堵幽,只有在類型和值都相同時(shí)才被認(rèn)為相等。
let a: number = 5
let b: string = "5"
// 使用 ==
console.log(a == b);  // 輸出: true弹澎,因?yàn)樵诒容^時(shí)會(huì)進(jìn)行類型轉(zhuǎn)換
// 使用 ===
console.log(a === b);  // 輸出: false谐檀,因?yàn)閲?yán)格相等要求類型和值都相同

let n1 = 5
let n2 = 6
console.log(n1 == n2)//false
console.log(n1 === n2)//false

7.4 in

在 TypeScript 中,in 關(guān)鍵字主要用于檢查對(duì)象是否包含某個(gè)屬性裁奇。它可以用于兩個(gè)場(chǎng)景:

  • 檢查對(duì)象是否包含某個(gè)屬性
let myObject = { key1: 'value1', key2: 'value2' };

if ('key1' in myObject) {
  console.log('myObject has key1 property');
} else {
  console.log('myObject does not have key1 property');
}
  • 遍歷對(duì)象的屬性
let myObject = { key1: 'value1', key2: 'value2' };
for (let key in myObject) {
  console.log(`Property: ${key}, Value: ${myObject[key]}`);
}
//[LOG]: "Property: key1, Value: value1" 
//[LOG]: "Property: key2, Value: value2" 

八. 函數(shù)

8.1 調(diào)用簽名

可以給函數(shù)綁定一個(gè)屬性

type DescriptionFuntion = {
    description: string
    (arg: number): boolean
}

function doSomething(fn: DescriptionFuntion) {
  console.log(fn.description + " return" + fn(6))
}

function fn(n: number) {
  console.log(n)
  return true
}
fn.description = "調(diào)用簽名"

doSomething(fn)

//[LOG]: 6 
//[LOG]: "調(diào)用簽名return true" 

8.2 構(gòu)造簽名

class Cls {
  name: string
  constructor(name: string) {
    this.name = name
  }
}

//方法1  字面量方式構(gòu)造簽名
function fn0(cls: new(name: string) => Cls): Cls {
   return new cls("aaa")
}
const cls0: Cls = fn0(Cls)
console.log(cls0)

function fnt<T>(cls: new(name: string) => T): T {
    return new cls("ttt")
}
const clst: Cls = fnt(Cls)
console.log(clst)

//方法2  接口對(duì)象字面量方式構(gòu)造簽名
function fn1(cls: {new (name: string): Cls}, name: string): Cls {
  return new cls(name)
}
const cls1: Cls = fn1(Cls, "bbb")
console.log(cls1)

//方法3 使用type或者interface
type ClsConstrutor = {
  new (name: string):Cls
}
function fn2(cls: ClsConstrutor): Cls {
  return new cls("ccc")
}

九.泛型

9.1 類型限制

//泛型T必須要有一個(gè)length屬性
function longest<T extends {length: number}> (a: T, b: T) {
  return a.length > b.length ? a : b 
}

9.2 指定類型參數(shù)

function combine<T>(arr1: T[], arr2: T[]): T[] {
  return arr1.concat(arr2)
}
combine([1, 2, 3], [4, 5, 6])

// 報(bào)錯(cuò)了, 因?yàn)轭愋屯茢酁閚umber[]
// combine([1, 2, 3], ["a", "b", "c"])

// 如果你非得亂搞,那需要這樣做, 聲明數(shù)組的類型
let arr = combine<number | string> ([1, 2, 3], ["a", "b", "c"])
console.log(arr)//[LOG]: [1, 2, 3, "a", "b", "c"] 

9.3 泛型約束

interface haveLength {
    length: number
}
// 傳入的參數(shù)需要有l(wèi)ength屬性
function use<T extends haveLength>(args: T) {
    console.log(args.length)
}
use("123")//[LOG]: 3

9.4 泛型約束中使用類型參數(shù)

function getProperties<Type, Key extends keyof Type>(t: Type, k: Key) {
    return t[k]
}
let obj = {
    a: 1,
    b: 2
}
let ret1 = getProperties(obj, "a")
console.log(ret1)//[LOG]: 1 

//let ret2 = getProperties(obj, "c")//報(bào)錯(cuò), 沒(méi)有這個(gè)key

十. This關(guān)鍵字

  • this的指向問(wèn)題
    在 TypeScript 中桐猬,你可以在函數(shù)參數(shù)中使用 this 參數(shù),這允許你顯式地指定函數(shù)的調(diào)用方刽肠。通常溃肪,在函數(shù)內(nèi)部,this 關(guān)鍵字用于引用當(dāng)前對(duì)象音五,但對(duì)于一些情況惫撰,尤其是在回調(diào)函數(shù)或異步代碼中,JavaScript 的默認(rèn)行為可能導(dǎo)致 this 的值不是你期望的對(duì)象躺涝。

  • this和箭頭函數(shù), 注意:this在冒號(hào)前面.如果this在冒號(hào)后面,this就是指向調(diào)用方

class MyClass {
    name = "MyClass"
    getName() {
        return this.name
    }
    getConstName = () => {
        return this.name
    }
    getThisName(this: MyClass) {
        return this.name
    }
}

//沒(méi)問(wèn)題
let cls = new MyClass()
console.log(cls.getName())//[LOG]: "MyClass" 

//換個(gè)方式就有問(wèn)題了
//getName獲取到的是cls1的, 而不是MyClass的
let cls1 = {
    name: "cls1Name",
    getName: cls.getName//這是一個(gè)方法
}
console.log(cls1.getName())//[LOG]: "cls1Name" 


//怎么強(qiáng)行輸出MyClass呢.
//1.使用=>, 把方法改成函數(shù)
let cls2 = {
    name: "cls2Name",
    getName: cls.getConstName//這是一個(gè)方法
}
console.log(cls2.getName())//[LOG]: "MyClass" 
//2.使用this關(guān)鍵字
let cls3 = {
    name: "cls3Name",
    getName: cls.getThisName
} 
console.log(cls3.getName())//報(bào)錯(cuò), 直接不讓cls3使用自己的name,只能使用MyClss的name

F

  1. type和interface的區(qū)別
    基本相同, 但是interface更容易擴(kuò)展
//type后面跟個(gè)=
type Cls0 = {
  a: number
}
let a0: Cls0 = {a: 10}
//使用&符號(hào)type增加擴(kuò)展
type Cls1 = Cls0 & {
  b: number
}
let a1: Cls1 = {a: 10, b: 20}
console.log(a1)


//interface后面沒(méi)有=
interface Bill{ 
  a: number
}
let b0: Bill = {a: 10}
// 使用extend增加擴(kuò)展
interface Bill1 extends Bill {
  b: number
}
let b1: Bill1 = {a: 10, b: 20}
console.log(b1)


//使用extend給type增加擴(kuò)展  0.0
interface Cls2 extends Cls0 {
  c: number
}
let c: Cls2 = {a: 10, c: 30}
console.log(c)


//interface可以多地方聲明. type多地方聲明則會(huì)報(bào)錯(cuò)
interface Win {
  a: string
}
interface Win {
  b: number
}
const w: Win = {
  a: "this is a stirng",
  b: 666
}
console.log(w)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末厨钻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夯膀,老刑警劉巖诗充,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異诱建,居然都是意外死亡蝴蜓,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門俺猿,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)茎匠,“玉大人,你說(shuō)我怎么就攤上這事押袍∷忻埃” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵谊惭,是天一觀的道長(zhǎng)汽馋。 經(jīng)常有香客問(wèn)我,道長(zhǎng)午笛,這世上最難降的妖魔是什么惭蟋? 我笑而不...
    開封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任苗桂,我火速辦了婚禮药磺,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘煤伟。我一直安慰自己癌佩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開白布便锨。 她就那樣靜靜地躺著围辙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪放案。 梳的紋絲不亂的頭發(fā)上姚建,一...
    開封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天,我揣著相機(jī)與錄音吱殉,去河邊找鬼掸冤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛友雳,可吹牛的內(nèi)容都是我干的稿湿。 我是一名探鬼主播,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼押赊,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼饺藤!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤涕俗,失蹤者是張志新(化名)和其女友劉穎罗丰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體咽袜,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡丸卷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了询刹。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谜嫉。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖凹联,靈堂內(nèi)的尸體忽然破棺而出沐兰,到底是詐尸還是另有隱情,我是刑警寧澤蔽挠,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布住闯,位于F島的核電站,受9級(jí)特大地震影響澳淑,放射性物質(zhì)發(fā)生泄漏比原。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一杠巡、第九天 我趴在偏房一處隱蔽的房頂上張望量窘。 院中可真熱鬧,春花似錦氢拥、人聲如沸蚌铜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)冬殃。三九已至,卻和暖如春叁怪,著一層夾襖步出監(jiān)牢的瞬間审葬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工奕谭, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留涣觉,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓展箱,卻偏偏與公主長(zhǎng)得像旨枯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子混驰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350