欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

typescript返回值類型和參數(shù)類型的具體使用

 更新時間:2022年06月22日 11:00:06   作者:恪愚  
本文主要介紹了typescript返回值類型和參數(shù)類型的具體使用文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

返回值類型

在 JavaScript 中,我們知道一個函數(shù)可以沒有顯式 return,此時函數(shù)的返回值應該是 undefined:

function fn() {
  // TODO
}
console.log(fn()); // => undefined

需要注意的是,在 TypeScript 中,如果我們顯式聲明函數(shù)的返回值類型為 undfined,將會得到如下所示的錯誤提醒。

function fn(): undefined { // ts(2355) A function whose declared type is neither 'void' nor 'any' must return a value
  // TODO
}

此時,正確的做法是使用 void 類型來表示函數(shù)沒有返回值的類型(這是“廢柴” void 類型唯一有用的場景),示例如下:

function fn1(): void {
}
fn1().doSomething(); // ts(2339) Property 'doSomething' does not exist on type 'void'

我們可以使用類似定義箭頭函數(shù)的語法來表示函數(shù)類型的參數(shù)和返回值類型,此時=> 類型僅僅用來定義一個函數(shù)類型而不用實現(xiàn)這個函數(shù)。

需要注意的是,這里的=>與 ES6 中箭頭函數(shù)的=>有所不同。TypeScript 函數(shù)類型中的=>用來表示函數(shù)的定義,其左側是函數(shù)的參數(shù)類型,右側是函數(shù)的返回值類型;而 ES6 中的=>是函數(shù)的實現(xiàn)。

在對象(即接口類型)中,除了使用這種聲明語法,我們還可以使用類似對象屬性的簡寫語法來聲明函數(shù)類型的屬性,如:

interface Entity {
    add: (a: number, b: number) => number;
    del(a: number, b: number): number;
}
const entity: Entity = {
    add: (a, b) => a + b,
    del(a, b) {
      return a - b;
    },
};

在某種意義上來說,這兩種形式都是等價的。但是很多時候,我們不必或者不能顯式地指明返回值的類型,這就涉及可缺省和可推斷的返回值類型的講解。

可缺省和可推斷的返回值類型

幸運的是,函數(shù)返回值的類型可以在 TypeScript 中被推斷出來,即可缺省。

函數(shù)內(nèi)是一個相對獨立的上下文環(huán)境,我們可以根據(jù)入?yún)χ导庸び嬎?,并返回新的值。從類型層面看,我們也可以通過類型推斷加工計算入?yún)⒌念愋停⒎祷匦碌念愋?,示例如下?/p>

function computeTypes(one: string, two: number) {
  const nums = [two];
  const strs = [one]
  return {
    nums,
    strs
  } // 返回 { nums: number[]; strs: string[] } 的類型 
}

請記?。哼@是一個很重要也很有意思的特性,函數(shù)返回值的類型推斷結合泛型可以實現(xiàn)特別復雜的類型推斷,比如 Redux Model 中 State、Reducer、Effect 類型的關聯(lián)。

一般情況下,TypeScript 中的函數(shù)返回值類型是可以缺省和推斷出來的,但是有些特例需要我們顯式聲明返回值類型,比如 Generator 函數(shù)的返回值。

Generator 函數(shù)的返回值

ES6 中新增的 Generator 函數(shù)在 TypeScript 中也有對應的類型定義。

Generator 函數(shù)返回的是一個 Iterator 迭代器對象,我們可以使用 Generator 的同名接口泛型或者 Iterator 的同名接口泛型表示返回值的類型(Generator 類型繼承了 Iterator 類型),示例如下:

type AnyType = boolean;
type AnyReturnType = string;
type AnyNextType = number;
function *gen(): Generator<AnyType, AnyReturnType, AnyNextType> {
  const nextValue = yield true; // nextValue 類型是 number,yield 后必須是 boolean 類型
  return `${nextValue}`; // 必須返回 string 類型
}

注意:TypeScript 3.6 之前的版本不支持指定 next、return 的類型,所以在某些有點歷史的代碼中,我們可能會看到 Generator 和 Iterator 類型不一樣的表述。

參數(shù)類型

關于 JS 中函數(shù)的參數(shù),在es6之后,統(tǒng)共可以分為:可選參數(shù)、默認參數(shù)、剩余參數(shù) 幾個特性。

可選參數(shù)和默認參數(shù)

在實際工作中,我們可能經(jīng)常碰到函數(shù)參數(shù)可傳可不傳的情況,當然 TypeScript 也支持這種函數(shù)類型表達,如下代碼所示:

function log(x?: string) {
  return x;
}
log(); // => undefined
log('hello world'); // => hello world

在上述代碼中,我們在類型標注的:前添加?表示 log 函數(shù)的參數(shù) x 就是可缺省的。

也就是說參數(shù) x 的類型可能是 undefined(第 5 行調(diào)用 log 時不傳入實參)類型或者是 string 類型(第 6 行調(diào)用 log 傳入 'hello world' 實參),那是不是意味著可缺省和類型是 undefined 等價呢?

function log(x?: string) {
  console.log(x);
}
function log1(x: string | undefined) {
  console.log(x);
}
log();
log(undefined);
log1(); // ts(2554) Expected 1 arguments, but got 0
log1(undefined);

顯而易見:這里的 ?: 表示參數(shù)可以缺省、可以不傳,但如果傳則一定是string類型。也就是說調(diào)用函數(shù)時,我們可以不顯式傳入?yún)?shù)。但是,如果我們聲明了參數(shù)類型為 xxx | undefined,就表示函數(shù)參數(shù)是不可缺省且類型必須是 xxx 或者 undfined。

因此,在上述代碼中,log1 函數(shù)如果不顯示傳入函數(shù)的參數(shù),TypeScript 就會報一個 ts(2554) 的錯誤,即函數(shù)需要 1 個參數(shù),但是我們只傳入了 0 個參數(shù)。

在 ES6 中支持函數(shù)默認參數(shù)的功能。而 TypeScript 會根據(jù)函數(shù)的默認參數(shù)的類型來推斷函數(shù)參數(shù)的類型,示例如下:

function log(x = 'hello') {
    console.log(x);
}
log(); // => 'hello'
log('hi'); // => 'hi'
log(1); // ts(2345) Argument of type '1' is not assignable to parameter of type 'string | undefined'

在上述示例中,根據(jù)函數(shù)的默認參數(shù) 'hello' ,TypeScript 推斷出了 x 的類型為 string | undefined。

當然,對于默認參數(shù),TypeScript 也可以顯式聲明參數(shù)的類型(一般默認參數(shù)的類型是參數(shù)類型的子集時,我們才需要這么做)。不過,此時的默認參數(shù)只起到參數(shù)默認值的作用,如下代碼所示:

function log1(x: string = 'hello') {
    console.log(x);
}
// ts(2322) Type 'string' is not assignable to type 'number'
function log2(x: number = 'hello') {
    console.log(x);
}
log2();
log2(1);
log2('1'); // ts(2345) Argument of type '"1"' is not assignable to parameter of type 'number | undefined'

上例函數(shù) log2 中,我們顯式聲明了函數(shù)參數(shù) x 的類型為 number,表示函數(shù)參數(shù) x 的類型可以不傳或者是 number 類型。因此,如果我們將默認值設置為字符串類型,編譯器就會拋出一個 ts(2322) 的錯誤。

同理,如果我們將函數(shù)的參數(shù)傳入了字符串類型,編譯器也會拋出一個 ts(2345) 的錯誤。

請再次注意:函數(shù)的默認參數(shù)類型必須是參數(shù)類型的子類型:

function log3(x: number | string = 'hello') {
    console.log(x);
}

在上述代碼中,函數(shù) log3 的函數(shù)參數(shù) x 的類型為可選的聯(lián)合類型 number | string,但是因為默認參數(shù)字符串類型是聯(lián)合類型 number | string 的子類型,所以 TypeScript 也會檢查通過。

剩余參數(shù)

在 ES6 中,JavaScript 支持函數(shù)參數(shù)的剩余參數(shù),它可以把多個參數(shù)收集到一個變量中。同樣,在TypeScript 中也支持這樣的參數(shù)類型定義,如下代碼所示:

function sum(...nums: number[]) {
    return nums.reduce((a, b) => a + b, 0);
}
sum(1, 2); // => 3
sum(1, 2, 3); // => 6
sum(1, '2'); // ts(2345) Argument of type 'string' is not assignable to parameter of type 'number'

在上述代碼中,sum 是一個求和的函數(shù),...nums將函數(shù)的所有參數(shù)收集到了變量 nums 中,而 nums 的類型應該是 number[],表示所有被求和的參數(shù)是數(shù)字類型。因此,sum(1, '2') 拋出了一個 ts(2345) 的錯誤,因為參數(shù) '2' 并不是 number 類型。

如果我們將函數(shù)參數(shù) nums 聚合的類型定義為 (number | string)[],如下代碼所示:

function sum(...nums: (number | string)[]): number {
    return nums.reduce<number>((a, b) => a + Number(b), 0);
}
sum(1, '2', 3); // 6

那么,函數(shù)的每一個參數(shù)的類型就是聯(lián)合類型 number | string,因此 sum(1, '2', 3) 的類型檢查也就通過了。

typescript中的常見報錯:

  • ts(2322)是一個靜態(tài)類型檢查的錯誤,在注解的類型和賦值的類型不同的時候就會拋出這個錯誤
  • ts(2355) :簡單來說就是:函數(shù)必須有一個返回值(報錯翻譯:聲明類型既不是void也不是any的函數(shù)必須返回一個值)
  • ts(2339): 在TypeScript中如果按JS的方式去獲取對象屬性時,可能會遇到。它表示Typescript在執(zhí)行代碼檢查時在該對象沒有定義相應屬性。解決方法有 —— 直接設置對象為any、對象斷言為any、將屬性.獲取方式改為數(shù)組式獲取三種
  • ts(2345):參數(shù)類型與預期不符
  • ts(2554):參數(shù)個數(shù)與預期不符

到此這篇關于typescript返回值類型和參數(shù)類型的具體使用的文章就介紹到這了,更多相關typescript返回值類型和參數(shù)類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論