面試題
1.類型推論 & 可賦值性
a.什么是類型推論?
若沒給定變量指定類型,ts會給標定一個類型,ts根據上下文
b.以下代碼ts推論出的類型是什么?
let a = 1024; // number
let b= '1024'; // string
const c = 'apple'; // apple
let d = [true, false, true]; // boolean[]
let e = {name: 'apple'} // object
let f = null; // any
c為什么是apple
c使用const定義的不會被重新復制,是字面量類型,是一個常量,是縮窄,不是拓寬
f為什么是null
ts在做推導時進行類型拓寬,會拓寬到any,拓寬到包容的類型中
可賦值性:數組、布爾、數字、對象、函數、類、字符串、字面量類型,滿足以下任一條件時,A類型可以賦值給B類型
(1)A是B的子類型
(2)A是any 類型
規則2是規則1的例外
2.類型斷言 指定值類型,縮小范圍 斷言就是讓ts別管了,類型轉換是變量類型實際改變
function formatInput(input:string):string{
return input.slice(0,10)
}
function getUserInput():string | number {
return 'test'
}
let input = getUserInput();
formatInput(input as string);
formatInput(<string>input);
3.type和interface的異同
interface側重於描述數據結構,type(類型別名)側重於描述類型
type age = number;
type dataType = number | string;
type Method = 'GET' | 'POST' | 'PUT' | 'DELETE';
type User = {
name: string
age:number
}
interface User1 extends User {
age:number
}
const user1:User1 = {
name:'John',
age:12
}
--相同點:
a.都可以描述一個對象或者函數
//interface
interface User {
name:string;
age:number;
}
interface SetUser {
(name:string,age:number):void;
}
//type
type User = {
name:string;
age:number;
}
type SetUser = (name:string,age:number):void
b.interface和type都可以擴展,interface可以extends type,type也可以extends interface.效果差不多,語法不同
// interface extends interface
interface Name {
name:string;
}
interface User extends Name {
age:number;
}
//type extends type
type Name = {
name:string;
}
type User = Nmae & {age:number}
//interface extends type
type Name = {
name:string;
}
interface User extends Name{
age:number
}
//type extends interface
interface Name {
name:string;
}
type User = Name & {age:number};
--不同點
a.類型別名可以用於其他類型(聯合類型、元祖類型、基本類型(原始值)),interface不支持 type強調類型,interface強調結構
type PartialPointX = {x:number};
type PartialPointY = {y:number};
//union(聯合)
type PartialPoint = PartialPointX | PartialPointY;
//tuple(元組)
type Data = [PartialPointX,PartialPointY];
//primitive(原始值)
type Name = Number;
//typeof的返回值
let div = document.creatElement('div');
type B = typeof div;
b.interface可以多次定義,並被視為合並所有聲明成員,type不支持
interface Point {
x:number;
}
interface Point {
y:number;
}
const point:Point = {x:1,y:2};
interface USer {
name:string;
age:number;
}
interface User {
sex:string;
}
//User接口為:
{
name:string;
age:number;
sex:string;
}
c.type能使用in關鍵字生成映射類型,但interface不行
type Keys = 'firstname' | 'surname';
type DudeType = {
[key in Keys]: string;
};
const test: DudeType = {
firstname:'Pawel',
surname:'Grzybek',
};
提問:
//1
type Options = {
baseURL: string
cacheSize?: number
env?: 'prod' | 'dev'
}
//2
class API {
constructor(options:Options){}
}
//3
new API({
baseURL:'http://myapi.site.com',
env:'prod'
})
//4
new API({
baseURL:'http://myapi.site.com',
badEnv:'prod'
})
//5
new API({
baseURL:'http://myapi.site.com',
badEnv:'prod'
} as Options)
//6
let badOptions = {
baseURL:'http://myapi.site.com',
badEnv: 'prod'
}
new API(badOptions)
//7
let options:Options = {
baseURL:'http://myapi.site.com',
badEnv: 'prod'
}
new API(badOptions)
4.裝飾器問題
--裝飾器分類及其裝飾器參數:
a.類裝飾器:類的構造函數
b.方法裝飾器:對於靜態成員來說是類的構造函數,對於實例成員是類的原型對象;成員的名字;成員的屬性描述符
c.訪問器裝飾器:對於靜態成員來說是類的構造函數,對於實例成員是類的原型對象;成員的名字;成員的屬性描述符
d.方法參數裝飾器:對於靜態成員來說是類的構造函數,對於實例成員來說是類的原型對象;參數的名字;參數在函數參數列表中的索引
e。屬性裝飾器:對於靜態成員來說是類的構造函數,對於實例成員來說是類的原型對象;成員的名字
--執行順序
a.有多個參數裝飾器s時:從最后一個參數依次向前執行
b.方法和方法參數中參數裝飾器先執行
c.類裝飾器總是最后執行
d.方法和屬性裝飾器,誰在前面誰先執行。因為參數屬於方法的一部分,所以參數會一直緊緊挨着方法執行
5.接口類型
屬性類接口 函數類接口 可索引接口 類類型接口 擴展接口