使用typescript推導(dǎo)已有變量的盲盒類型詳情
遷移盲盒
當(dāng)我們從JavaScript一鍵轉(zhuǎn)換Typescript的時候,any便是最省事的做法,對于維護并不友好(雖然能跑就行),同時每個變量對于我們來說都是盲盒,它到底是什么類型?
類型推導(dǎo)
基礎(chǔ)類型的推導(dǎo)
基礎(chǔ)數(shù)據(jù)類型的類型推導(dǎo)還是挺簡單的
let a = 1; type A = typeof a; // number; let b = '2' type B = typeof b; // string; let c; type C = typeof c; // undefined;
一個typeof就可以把原始值類型推導(dǎo)出來了!
我們整理下基礎(chǔ)數(shù)據(jù)類型有哪些?
// 沒錯,7種數(shù)據(jù)類型 type Base = string | number | boolean | null | undefined | symbol | bigint;
對象的推導(dǎo)
這里我們來實現(xiàn)下普通對象如何推導(dǎo)
let obj = { a: 1, b: '2', c: true, d: null };
type Obj = typeof obj;
// { a: number; b: string; c: boolean; d: null; }沒錯,也是這么簡單!
數(shù)組的推導(dǎo)
為什么上面的對象除開數(shù)組呢?因為數(shù)組在typescript比較特殊,既可以用元祖來聲明,又可以用數(shù)組來聲明
也可以說數(shù)組包含了元祖
type isContain = [1, 2] extends Array<number> ? true : false; // true
嘗試?yán)^續(xù)通過typeof來實現(xiàn)推導(dǎo)
let arr = [1, '2', null, false]; type Arr = typeof arr; // (string | number | boolean | null)[] ??? type Arr1 = typeof arr[0] // string | number | boolean | null ???
好吧,得到的竟然是聯(lián)合類型數(shù)組,是不是和我們預(yù)期的不一樣?
我們定義一個數(shù)組,卻沒有聲明類型,對于數(shù)組來說,默認(rèn)就是 Array,由于不斷填充了 number,string,null,boolean的值,最后變成了 Array<string | number | boolean | null>,而且是每一個元素都是聯(lián)合類型
重新整理下,我們需要的是啥?
[1, '2', null, false] -> [number, string, null, boolean]
我們要的是元祖 [number, string, null, boolean],而不是數(shù)組 Array<string | number | boolean | null>
整理下todo,我們需要的是:
- 固定長度的數(shù)組類型
- 每個元素都有獨立的類型
let arr = [1, '2', null, false] as const; type Arr = typeof arr; // readonly [1, '2', null, false] type Arr1 = typeof arr[0] // 1
第一個 todo 實現(xiàn)了,第二個有點像,但又不對,我們要的是數(shù)據(jù)類型,而不是某個具體的值
實現(xiàn)一個轉(zhuǎn)換類型的泛型
我們要的是 1 轉(zhuǎn) number, 'A' 轉(zhuǎn) string,只需要列出所有的基礎(chǔ)類型做轉(zhuǎn)換就可以了
type GetType<T> = T extends string ? string :
T extends number ? number :
T extends boolean? boolean :
T extends null ? null :
T extends undefined ? undefined :
T extends symbol ? symbol :
T extends bigint ? bigint : T;
type Arr1 = typeof arr[0] // number
type Arr2 = typeof arr[1] // string那再遍歷一次元祖就可以實現(xiàn)整個數(shù)組的類型轉(zhuǎn)換了
type TransArr<T extends Array<unknown>,
R extends unknown[] = []> = {
'loop': TransArr<T,
[...R,
T extends Base ?
GetType<T[R['length']]>: T[R['length']]
]
>,
'result': R,
}[T['length'] extends R['length'] ? 'result': 'loop'];
let arr = [1, '2', null, false] as const;
type Arr = typeof arr;
type ArrType = TransArr<Arr>; // [number, string, null, boolean]函數(shù)的推導(dǎo)
函數(shù)的推導(dǎo)其實沒有必要,為什么這么說,函數(shù)參數(shù)和值類型不可控,除個別操作符或者明確類型
如 (a, b) => a * b ,返回值一定是number
如 (a) => Promise.resolve(a),返回值一定是Promise
let fn1 = (a, b) => a * b;
type Fn1 = typeof fn1; // (a: any, b: any) => number
function fn2(a) {
return Promise.resolve(a);
}
type Fn2 = typeof fn2; // (a: any) => Promise<any>大多是函數(shù)經(jīng)過typeof后得到的結(jié)果是
(a: any, b: any, ...) => any;
這個類型可以限定參數(shù)數(shù)量更多的函數(shù)
function fn3(a, b, c) {
return a + b + c;
}
function fn4(d) {
return d + 1;
}
type Fn3 = typeof fn3; // (a: any, b: any, c: any) => any
type Fn4 = typeof fn4; // (d: any) => any
type F3_4 = Fn3 extends Fn4 ? true : false; // false
type F4_3 = Fn4 extends Fn3 ? true : false; // true也就是說,參數(shù)多的函數(shù)總是包含了參數(shù)少的函數(shù)
根據(jù)上面的判斷,我們可以通過這個來實現(xiàn)函數(shù)的判斷
type isFunc<T> = (() => any) extends T ? true : false;
完善推導(dǎo)
- 基礎(chǔ)類型直接返回類型
- 數(shù)組用TransArr泛型轉(zhuǎn)一次
- 函數(shù)直接返回typeof的值
- 遍歷對象則用keyof實現(xiàn)
type Trans<T> = T extends Base
? GetType<T> : T extends Array<unknown>
? TransArr<T> : isFunc<T> extends true
? T : {
[key in keyof T]: T[key] extends Base
? GetType<T[key]> : T[key] extends Array<unknown>
? TransArr<T[key]> : Trans<T[key]>;
};測試
let a1 = 1;
type test1 = Trans<typeof a1>; // number
let a2 = '2';
type test2 = Trans<typeof a2>; // string
let a3 = [1, '2', true, '3', 4] as const;
type test3 = TransArr<typeof a3>;
// [number, string, boolean, string, number]
let a4 = {
a: 1,
b: true,
c: {
a: 1,
b: [1, '2']
},
d: [true, null]
} as const;
type test4 = Trans<typeof a4>;
// {
// readonly a: number;
// readonly b: boolean;
// readonly c: {
// readonly a: number;
// readonly b: readonly [number, string];
// };
// readonly d: readonly [boolean, null];
// }
let a5 = {
a: [
{
b: [
{ c: 1 }
]
}
]
} as const;
type test5 = Trans<typeof a5>;
// {
// readonly a: readonly [{
// readonly b: readonly [{
// readonly c: number;
// }];
// }];
// }
let a6 = (a, b, c) => a + b + c;
type test6 = Trans<typeof a6>;
// (a: any, b: any, c: any) => any
let a7 = [
function fn() {
return 1;
},
(a, b) => a * b,
(a) => Promise.resolve(a)
] as const;
type test7 = TransArr<typeof a7>;
// [() => number, (a: any, b: any) => number, (a: any) => Promise<any>]
let a8 = {
a: 1,
b: [true, null],
c: [() => void, (a, b) => a],
d: {
e: [
(a, b) => null,
{
f: [1]
}
]
}
} as const;
type test8 = Trans<typeof a8>;
// {
// readonly a: number;
// readonly b: readonly [boolean, null];
// readonly c: readonly [() => undefined, (a: any, b: any) => any];
// readonly d: {
// readonly e: readonly [(a: any, b: any) => null, {
// readonly f: readonly [number];
// }];
// };
// }到此這篇關(guān)于使用typescript推導(dǎo)已有變量的盲盒類型詳情的文章就介紹到這了,更多相關(guān)typescript盲盒類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
獲取3個數(shù)組不重復(fù)的值的具體實現(xiàn)
先用concat拼接數(shù)組 ,再使用一個對象、一個新數(shù)組(用于存放不重復(fù)的數(shù)組)具體實現(xiàn)如下,感興趣的朋友可以參考2013-12-12
js實現(xiàn)網(wǎng)頁的兩個input標(biāo)簽內(nèi)的數(shù)值加減(示例代碼)
下面小編就為大家?guī)硪黄猨s實現(xiàn)網(wǎng)頁的兩個input標(biāo)簽內(nèi)的數(shù)值加減(示例代碼)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08
網(wǎng)站被黑的假象--ARP欺騙之頁面中加入一段js
網(wǎng)站被黑的假象--ARP欺騙之頁面中加入一段js...2007-05-05
layui的表單驗證支持ajax判斷用戶名是否重復(fù)的實例
今天小編就為大家分享一篇layui的表單驗證支持ajax判斷用戶名是否重復(fù)的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-09-09

