亚洲日本永久一区二区_国产精品k频道网址导航_首页aⅴ色老汉中文字幕_免费深夜全片观看_9久久9毛片又大又硬又粗_国产精品成亚洲电影_日韩不用播放器的av_欧美特色特黄视频

3 個加強理解TypeScript 的面試問題

3 個加強理解TypeScript 的面試問題

TypeScript 作為 JavaScript 的超集,讓 JavaScript 越來越像一門“正經的”語言。和純粹的 JavaScript 語言相比,TypeScript 提供靜態的類型檢查,提供類的語法糖(這一點是繼承了 ES6 的實現),讓程序更加規范和緊湊,為使用 JavaScript 開發大型項目提供了必要的條件。本文介紹 3 個加強理解的面試問題。

A 的類型是什么,為什么?

通常在面試中會有一些閱讀程序語句給出結果的問題,一般是一段非常簡單的代碼,是檢驗候選人對基礎的理解。

type A = number & string;

答案很簡單,A 的類型是 never,為什么呢?因為 & 是交集運算符,如果將字符串和數字視為一組值,則可以對其進行賦值。那么字符串集合和數字集合的交集是空集,在 TypeScript 中用 never 表示,換句話說,不存在可以同時屬于數字和字符串的值:

字符串集合和數字集合的交集是空集

運行時驗證

假設候選人成功回答了第一個問題,這意味著大概率候選人對基礎有了很好的理解。現在,需要變得更復雜一點,變得非常實際:假設有一個 API,它返回給我們一個 JSON 字符串,其中包含有關用戶的信息。

問題是:如何驗證用戶對象,并確保它確實滿足 User 類型?

type User = {
  name: string;
  age: number;
};

const data = `{"name":"Bob","age":30}`;
const user: User = JSON.parse(data);

console.log(`Username: ${user.name.toLowerCase()}`);
console.log(`Age: ${user.age.toFixed(0)}`);

答案基本上有兩種方式:

首先,如果 User 類型很小,比如現在只有兩個字段,這對我們來說沒問題,那么我們可以編寫一個簡單的驗證函數:

function isUser(obj: unknown): obj is User {
  return (
    typeof obj['name'] === 'string' && 
    typeof obj['age'] === 'number'
  );
}

并像這樣使用它:

const data = `{"name":"Bob","age":30}`;
const user = JSON.parse(data); // user type if any here

if (isUser(user)) {
    console.log(`Username: ${user.name.toLowerCase()}`);
    console.log(`Age: ${user.age.toFixed(0)}`);
}

第二種變體,它更方便——使用你喜歡的任何庫來使用模式驗證:class-validatorzodruntypesjoi 等:

import Joi from "joi";

const UserSchema = Joi.object({
    name: Joi.string(),
    age: Joi.number(),
});

const data = `{"name":"Bob","age":30}`;
const userData = JSON.parse(data);

try {
    const user = UserSchema.validate(userData);

    console.log(`Username: ${user.name.toLowerCase()}`);
    console.log(`Age: ${user.age.toFixed(0)}`);
} catch (e) {}

這個問題不僅要檢查有關數據驗證的知識,還要檢查候選人對技術堆棧的了解程度,可以通過哪些方式完成等。

在類型中使用遞歸

最后一個問題通常是實用的,它是關于如何編寫遞歸類型的。在此示例中,需要問題的解決方案:假設正在編寫一個函數 find() 來搜索數據庫中的用戶。問題是該類型 User 具有地址等屬性,它也是一個對象。想以 find() 這種方式構建函數,這樣可以通過 User 的嵌套屬性進行搜索,并提供完整的類型支持:

function find<T>(criteria: ...): T[] {
    ...
}

type User = {
    id: number;
    name: string;
    address: {
        country: string;
        city: string;
        house: string;
        zipcode: string;
    };
};

// in this example im searching by country only, even if 
// address has other properties.

const users = find({
    address: { coutry: 'CN' }
});

如何實現:創建另一個名為 DeepPartial 的類型,并在 find() 函數中使用它作為條件參數:

type DeepPartial<T> = {
    [P in keyof T]?: DeepPartial<T[P]>;
};

function find<T>(criteria: DeepPartial<T>): T[] {
    ...
}

type User = {
    id: number;
    name: string;
    address: {
        country: string;
        city: string;
        house: string;
        zipcode: string;
    };
};

const users = find({
    address: { coutry: 'UK' }
});

DeepPartial<T> 幾乎與 Partial<T> 一樣工作,但唯一的區別是它遞歸地應用于對象的每個嵌套屬性:

type User = {
    id: number;
    name: string;
    address: {
        country: string;
        city: string;
        house: string;
        zipcode: string;
    };
};

// DeepPartial<User>
type DeepPartiallUser = {
    id?: number;
    name?: string;
    address?: {
        country?: string;
        city?: string;
        house?: string;
        zipcode?: string;
    };
};

希望通過上面這些 TypeScript 的小例子可以幫助更好地使用它,并且在還不知道這些東西的情況下寫出更好的代碼。