在使用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編譯結果對照