如何使用 vue + typescript 編寫頁面 (typescript簡單語法篇)

董輝輝發表於2019-02-23

在使用typescript編寫專案之前,需要有一定的js【es6】基礎知識。在學習ts的過程中,類比js的差異,做到基本結合。 開發中除去js報錯的部分,大部分會受到ts的語義限定。

typescript基本內容

1. 變數申明

變數申明的時候,和js一樣但又不一樣。一樣的是變數申明符號是一樣的,不一樣的是需要附加型別限定。如果你是一個強型別的語言開發者

// js的宣告
var name;
let age;
const eat;
function play(bool){}
複製程式碼
// ts的宣告
var name:string;
let age:number;
const eat:Function; //  Function是型別,而function是用來宣告函式變數的,請不要用混
function run(bool:string):void { 
    /*
    傳參和基本一樣,需要限定傳值型別,
    在函式的引數列表後面需要加上返回值限定
    */
}
複製程式碼

型別申明時,有一個通用型別 any,這個表示這個變數可以接受任意型別的值,並且語法器也會忽略掉當前引數為null/undefined的情況。建議:除非特殊情況,儘量不要使用any作為引數型別,以便後期修改時,發生不必要的錯誤。

1.1 其他情況

// 大部分時候,我們會宣告成這種情況
// 但是在使用時卻發現,不能賦值,push值。
var classes:[];
// 實際上上面的那個等價於 
var classes:Array<never>;
// 或者等價於
var classes:never[];
複製程式碼

never ts獨有的修飾型別,表示當前什麼也沒有。和undefined/null不同,ts只存在never的申明,不存在never這個值。

// 當使用
var a:never;
var b = a;
// 此時的a會被語法提示,在賦值前使用了a。因此,需要將a先初始化才能使用,但是又沒有一種值叫never,因此a是無效的宣告型別。

// 那麼,我們一定要用呢?
// 藉助陣列實現
var a:never[] = [];
var b:never = a[0];

// 如果在物件裡宣告使用never呢?
var a = { b:never /*Error: “never”僅表示型別,但在此處卻作為值使用。 */ }

複製程式碼

2. class 物件導向的類

  • 單獨js寫法和ts並無不同,並且不支援多繼承
class A {  }
class B extends A { }

//子類使用建構函式時,需要有效呼叫父級建構函式
class Animal { 
    name:string;
    constructor(name:string){
        this.name = name;
    } 
}
class Dog extends Animal {
    constructor(name:string){ 
        super(name)
    } 
}
複製程式碼
  • js沒有interface,但是在ts下有,支援多實現介面
interface A {  }
interface B extends A { }
class C implements A,B { }
複製程式碼

interface 可以用來型別限定嗎? 答案是可以。對於ts來說,所謂型別限定僅僅就是屬性型別和名稱相符合,和型別和名稱沒有太大關係


interface A { name: string; age: number }
interface B { name: string; age: number }
class C { name!: string; age!: number }
var a: A = new C;
var b: B = new C;
var c: C;
// 使用非空型別時,需要先初始化值才可以使用
// 否則就會報錯 Error:在賦值前使用了變數“c”。
a = b = c;
複製程式碼

3. 申明型別不可變

js支援var重複申明,ts有<條件>的支援重複宣告

/* 後續變數宣告必須屬於同一型別。變數“a”必須屬於型別“string”,但此處卻為型別“number” */
var a:string;
var a:number;

// 重複宣告印證了,型別只和屬性相關,和名稱無關
interface A { name: string; age: number }
interface B { name: string; age: number }
class C { name!: string; age!: number }
var a: A;
var a: B;
var a: C;
複製程式碼

4.!:?:

在我們編寫程式碼的時候,經常會遇到 !: ?:這兩個組合符號,它們和 : 有什麼不同?

!: 表示一定存在,?:表示可能不存在 這兩種在語法上叫賦值斷言

因此:

 /* : 可以在任何需要的場合使用 */
 var a:number;
 
 // 不可以申明變數的時候使用
 var a!:number;
 var a?:number;
 
 // ?: 不可以字面量賦值時使用
 var a = { name?:"Pluto" }
複製程式碼

關於賦值斷言:通常會在class中看見他們的身影

class a {
    sad!: string;
    // 肯定斷言不能賦初值
    sad!: string = 'so sad';
    
    // 但是否定斷言,就可以
    age?: number = 2;
    
    bg = { age!: 16 }
}
複製程式碼

在Vue中最常見的肯定斷言就是prop還有store引入了,因為我們確信他們已經存在了

@Component
export default class MyComponent extends Vue {
    @Prop({ default : "" }) myName !: string;
    @State  mystate !: boolean;
}
複製程式碼

在Vue中最常見的否定斷言就是函式傳參和型別定義

interface A { 
    name:string
    /* 賦值時,age不是必選項,因此可以不使用 */
    age?:number
}

var a:A = { 
    name:"16"
}

function getSome(some?:string){
    /* 通常函式我們使用 給函式引數賦初始值的形式而不是用這種形式 */
    return some||""
}
function getSome(some:string=""){
    return some
}
複製程式碼

5. 賦初值屬性

ts中 class定義的屬性如果沒有賦初值,編譯後是不存在的

class A {
    name!:string;
}
new A() .hasOwnProperty("name") // false
複製程式碼

更多內容 線上TS編譯結果對照

上一章 如何使用 vue + typescript 編寫頁面 (Vue生命週期函式)

相關文章