Typescript語法入門

最近公司項目開始統一使用Typescript了,所以自己也是開始認真的學習了一下typescript,還是很有收獲的!下面分享給大家

基礎知識

  1. 基礎
let isDone: boolean = false;

let decimal: number = 6;

let color: string = "blue";

// 數組,有兩種寫法
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];

// 元組(Tuple)
let x: [string, number] = ["hello", 10];
// 元組類型是一個不可變的數組,長度、類型是不可變的。

// 當添加越界的元素時,它的類型會被限制為元組中每個類型的聯合類型
x.push('123')
x.push(123)
x.push(true)   // error, 不能添加非字符串和 number 的值

// 枚舉  通過enum則不能修改定義好的值了 
enum Color {Red = 1, Green = 2, Blue = 4}
let c: Color = Color.Green;
//  const Color1 = { Red: 1, Green: 2, Blue : 4}
//  上面Color1可以修改里面的值 例如Color.Red = 5; 枚舉就無法修改了

//枚舉的成員從0開始遞增,并且key 和 value 會互相映射
enum Colors { Red, Yellow, Blue }
Colors['Red'] === 0 // true  從0開始遞增
Colors[0] === 'Red' // 相互映射

// 枚舉事實上會編譯成如下
var Color;
(function (Color) {
    Color[Color["Red"] = 0] = "Red";
    Color[Color["Yellow"] = 1] = "Yellow";
    Color[Color["Blue"] = 2] = "Blue";
})(Color || (Color = {}));


// 不確定的可以先聲明為any
let notSure: any = 4;

// 聲明沒有返回值
function warnUser(): void {
    alert("This is my warning message");
}

let u: undefined = undefined;

let n: null = null;

// 類型永遠沒返回
function error(message: string): never {
    throw new Error(message);
}

// 類型主張,就是知道的比編譯器多,主動告訴編譯器更多信息,有兩種寫法
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
let strLength: number = (someValue as string).length;

  1. 封裝
private/protected/public
  1. interface 接口
interface SystemConfig {
    attr1: string;
    attr2: number;
    func1(): string;
    func2(): void;
}
<!-- 我們給軟件定了一個系統參數的配置接口,他定義了系統配置的形狀,有兩個屬性attr1和attr2,兩個方法func1和func2,這樣如果定義了const systemConfig: SystemConfig = {},那systemConfig就不能隨意修改了,他有形狀了。 -->

也可以用implements來實現接口,這樣可以實現類似更為靈活的繼承,如:

class A extends BaseClass implements BaseInterface1, BaseInterface2 {}

<!-- 類A繼承了BaseClass,并且繼承了BaseInterface1和BaseInterface2兩個接口 -->
// 接口也是可以繼承接口的
interface Fa {
  surname: string
}

interface Son extends Fa {
  name: string
}

const obj: Son = {
  surname : 'z',
  name: 'zc'
}

class Fa {
  constructor() {}
  suck(){

  }
}

interface Son extends Fa {
  suck():void;
  name: string;
}
  1. 命名空間 module/namespace
namespace Module1 {
  export interface SubModule1 {}
  
  export interface SubModule2 {}
}
const module: Module1.SubModule = {}

  1. 聲明文件 declare

declare 定義的類型只會用于編譯時的檢查,編譯結果中會被刪除。

在開發過程中不可避免要引用其他第三方的 JavaScript 的庫。雖然通過直接引用可以調用庫的類和方法,但是卻無法使用TypeScript 諸如類型檢查等特性功能。為了解決這個問題,需要將這些庫里的函數和方法體去掉后只保留導出類型聲明,而產生了一個描述 JavaScript 庫和模塊信息的聲明文件。通過引用這個聲明文件,就可以借用 TypeScript 的各種特性來使用庫文件了。

假如我們想使用第三方庫,比如 jQuery,我們通常這樣獲取一個 id 是 foo 的元素:

$('#foo');
// 或
jQuery('#foo');

但是在 TypeScript 中,我們并不知道 $ 或 jQuery 是什么東西:

jQuery('#foo');

// index.ts(1,1): error TS2304: Cannot find name 'jQuery'.

這時,我們需要使用 declare 關鍵字來定義它的類型,幫助 TypeScript 判斷我們傳入的參數類型對不對:

declare var jQuery: (selector: string) => any;

jQuery('#foo');

declare 定義的類型只會用于編譯時的檢查,編譯結果中會被刪除。

上例的編譯結果是:

jQuery('#foo');

聲明文件
聲明文件以 .d.ts 為后綴,例如:

runoob.d.ts
聲明文件或模塊的語法格式如下:

declare module Module_Name {
}
TypeScript 引入聲明文件語法格式:

/// <reference path = " runoob.d.ts" />

  1. 泛型
function makeState<S>() {
  let state: S
  function getState() {
    return state
  }
  function setState(x: S) {
    state = x
  }
  return { getState, setState }
}


// 限制它就只能輸入輸出number和string類型
function makeState<S extends number | string>() {
  let state: S
  function getState() {
    return state
  }
  function setState(x: S) {
    state = x
  }
  return { getState, setState }
}
// 如果我傳入boolean類型
const boolState = makeState<boolean>()

// 泛型的默認類型
function makeState<S extends number | string = number>()



// https://segmentfault.com/a/1190000021219586

泛型其實可以當作普通函數在聲明時的一個參數,這個參數代表類型。
我們可以給函數值參數設置默認值,
也可以通過typescipt的泛型給函數類型參數設置默認值。

function regularFunc(x = 2)
regularFunc()
function genericFunc<T = number>()
genericFunc()

其實上面已經涉及到泛型約束了,我們再來看一下更具體的泛型約束

//泛型無法知道具體的類型,所以無法操作它的屬性和方法
function Test<T> (a:T):void {
  console.log(a.length);  // error
}
Test<string>('1')

interface hasLengthProp {
    length : number;
}
function Test<T extends hasLengthProp>(a:T):void {
    console.log(a.length);
}
  1. 別名
type strAria = string; // 給 string 類型定義了 strAria別名
const str: strAria = 'abc';

type fnAria = () => string;
function (callback:fnAria):void {
    callback();
}

// 我們使用 type 定了一個字符串字面量類型 EventNames,它只能取三種字符串中的一種
type EventName = 'xm' | 'xh' | 'xb';
const str : EventName = 'xb'
const elseStr : EventName = 'xf' // error, 不在這幾個名字當中

  1. 聲明合并

就是說聲明兩個同樣的接口、類或者函數,會進行合并操作。

合并的屬性的類型必須是唯一的

interface Alarm {
    price: number;
     alert(s: string): string;
}
interface Alarm {
    weight: number;
    alert(s: string, n: number): string;
}
//===> 相當于
interface Alarm {
    price: number;
    weight: number;
    alert(s: string, n: number): string;
}

demo

我們可以先做一個簡單的 demo 來感受一下 TypeScript 的魅力。首先在 src/page 新建一個 Demo.tsx.
在其中定義一個無狀態組件 Hello。

import React from 'react';

const Hello = ({ name }) => <div>Hello,{name}</div>;

接下來我們使用它,

const App = () => <Hello />;

export default App;

我們發現他拋出了如下錯誤 :

不能將類型“{}”分配給類型“{ name: any; }”。類型“{}”中缺少屬性“name”。

因為我們使用了 name,Typescript 認為他是必填參數。如果不存在便認為程序錯誤,并造成編譯失敗。這可以幫助我們避免很多低級錯誤。

我們也可以使用 Class 語法來聲明組件,代碼如下:

class Message extends React.Component<{
  message: string;
}> {
  public render() {
    return <div>{this.props.message}</div>;
  }
}

我們可以通過 <> 的第一個參數來指定 props 的類型。通過第二個參數來指定 state 的類型
代碼如下:

class Message extends React.Component<
  {
    message: string;
  },
  {
    count: number;
  }
> {
  constructor(props) {
    super(props);
    this.state = {
      count: 0,
    };
  }
  public render() {
    return (
      <div>
        {this.props.message}
        {this.state.count}
      </div>
    );
  }
}

在這里,我們定義了一個 包含 count 的 state ,count 的類型為 number。然后在類 constructor 內部初始化 state。其余使用方式與 javascript 中相同。

我們可以自行修改 count,

public increment = () => {
  const { count } = this.state;
  this.setState({
    count: count + 1
  });
};

interface IProps {
  aProps: string;
  bProps: string;
}
interface IState {
  aState: string;
  bState: string;
}

class App extends React.PureComponent<IProps, IState> {
  state = {
    aState: '',
    bState: '',
  };
}

TS 對 類裝飾器的靜態解析還不支持, 建議React 和 Redux 的綁定函數 connect 用函數寫法

const mapStateToProps = (state: {}, ownProps: IProps) => {};
const mapDispatchToProps = {};

export default connect(mapStateToProps, mapDispatchToProps)(App);

以上是自己的一點點對typescript的基礎知識的了解,當然以上肯定會存在很多不足的地方,我會繼續更加深入的學習,歡迎各位提出寶貴的意見或建議,也希望能幫助到你從中獲得一些知識!

認真學前端 QQ群:619069335

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,963評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,348評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,083評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,706評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,442評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,802評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,795評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,983評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,542評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,287評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,486評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,030評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,710評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,116評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,412評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,224評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,462評論 2 378

推薦閱讀更多精彩內容

  • 如果說這世界上你只剩下做一件事的時間了,你會選擇做什么呢?這貌似很不好回答,但是就現在的我能做的那就是每天...
    睡不醒的懶蟲閱讀 155評論 0 0
  • 17.嘮叨男 我覺得史上最嘮叨的男人就是唐僧了:“哦,你想要啊?你想要啊,你想要說清楚就行了嘛。你想要的話我會給你...
    劉秀玲閱讀 2,061評論 37 29
  • 遠看山巒疊嶂, 近瞧郁郁蔥蔥, 師友相約游薊州, 住在望松。 林間花紅柳綠, 山坡果樹相嵌, 踏著薄霧等高處, 浮...
    9610ab214539閱讀 592評論 0 1
  • **Splendid** Adj. a splendid opportunity. **Aware** Adj. ...
    seedcm閱讀 248評論 0 0