<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                [TOC] >[success] # 高級類型(二) >[danger] ##### 多態的this類型 ~~~ 1.下面案例使用的鏈式調用,在1.7版本之前的ts這么寫,用PowCounter 時候,使用父類的add 和sub 會報錯,新版后這種返回this 會'含類或接口的子類型' ~~~ ~~~ class Counter{ constructor(public count:number=0){} add(value:number){ this.count +=value return this } sub(value:number){ this.count -=value return this } } class PowCounter extends Counter{ pow(value:number){ this.count = this.count ** value return this } } const powCounter = new PowCounter() powCounter.add(10).sub(5).pow(2) ~~~ >[danger] ##### 索引類型 -- 查詢操作符 (keyof) ~~~ 1.'keyof T'的結果為T上已知的公共屬性名的聯合 ~~~ ~~~ interface Info { name:string; age:number; } let info: keyof Info // 相當于let info: "name" | "age" info = 'name' info = 'age' // info = 'w' // 報錯 ~~~ * 泛型配合類型索引 ~~~ 1.{1} 說明我們想讓'infoValue'返回的都是string 類型的數組,所以age是數字類型因此報錯 2.{2} 是我們同過keyof 規定了只能是vauleInfo上存在的key 才行因此'ss' 報錯 3.{3} 這個是索引訪問操作符的一個用法下面會講解 ~~~ ~~~ / 現在有個一個需求 取出對象對應key 的value 值 // 這是我還不會用ts 時候工作天天寫的 沒有合理運用正確ts 寫法 // function getValue(obj:any,key:any[]){ // return key.map(item=>obj[item]) // } // 用索引查詢累心 和 泛型來寫正確寫上面的代碼邏輯 function getValue<T,K extends keyof T>(obj:T,key:K[]):T[K][]{ {3} return key.map((item)=> obj[item]) } const vauleInfo ={ name:'w', age:18 } let infoValue = getValue(vauleInfo, ['name', 'age']) // let infoValue:string[] = getValue(vauleInfo, ['name', 'age']) // 只返回string 類型的,添加age報錯 {1} // getValue(vauleInfo, ['name', 'age','ss']) // 報錯valueInfo 屬性沒有ss {2} ~~~ >[danger] ##### 索引訪問操作符 ~~~ 1.可以像js 對象一樣直接取出一個一個字段的類型 ~~~ ~~~ // 索引訪問操作符 interface Info1 { name: string, age: number } let infos:Info1['name'] // 相當于取出Info1 下角標name字段對應類型 let infos:string // infos =1 // 報錯 infos = 'w' // 實際應用 // 相當于只能返回的是T對象規定的值類型 function getProperty<T,K extends keyof T>(obj:T,names:K):T[K]{ return obj[names] } getProperty({name:'w',age:12},'name') // 返回的類型只能是 string 和數字 ~~~ >[danger] ##### keyof 和 索引訪問操作 ~~~ 1.來看這個案例首先keyof 取得是key 字段類型 2.索引取得是這個key對應的value類型 ~~~ ~~~ interface Dictionary<T> { [key: string]: T; } let keys: keyof Dictionary<number>; // string let value: Dictionary<number>['foo']; // number ~~~ * 這里是可以通過配置尋該是佛包含 null 和undefined ![](https://img.kancloud.cn/80/79/80792b62d0bccc475c41cd7bee6e19f9_466x62.png) ~~~ interface Type { a:never, b:never, c:null, d:undefined, e:string, f:number, } // 取出所有Type 接口對應的value 的類型 type Test = Type[keyof Type] const valueType:Test = 'w' ~~~ >[danger] ##### 映射類型 ~~~ 1.Readonly -- 所有字段只讀映射ts中分裝的形式 : type Record<K extends keyof any, T> = { [P in K]: T; }; 2.Partial -- 所有字段可選映射方法ts中分裝的形式 : type Partial<T> = { [P in keyof T]?: T[P]; }; 3.Pick -- 挑選指定字段ts中分裝的形式 : type Pick<T, K extends keyof T> = { [P in K]: T[P]; }; 4.Record -- 指定key ,value 類型ts中分裝的形式 : type Record<K extends keyof any, T> = { [P in K]: T; }; 5infer 、Exclude、 Extract、 NonNullable、 ReturnType 、InstanceType具體使用看下面案例(這些后期可以通過看ts實際實現) 6.ts 的'K in Keys' 寫法可以理解成js'for .. in',只不過他是針對類型的,使用這些寫法簡單小案例: type Keys = 'option1' | 'option2'; type Flags = { [K in Keys]: boolean }; ~~~ * 探討映射類型出現的原因 ~~~ 1.我們可以用'P in keyof T' 做一個類似循環的字段方式 ~~~ ~~~ // 一個場景 我們現在有一個接口,在一些情況下這些接口值是只能可讀的 interface Info1{ age:number; name:string; } const info1:Info1 ={ age:12, name:'w' } // 現在有另外一個變量和info1有相同的屬性但只是他的字段都是只讀 interface Info2{ readonly age:number, readonly name:string, } const info2:Info2 ={ age:12, name:'w' } // 現在產生一個問題 這樣對這種重復字段只是在使用定義不同的內容每次都要做重復操作 // 先使用泛型和類型別名來做一統一轉換的方法 type ReadonlyType<T> ={ readonly [P in keyof T]:T[P] } const infos3:ReadonlyType<Info1> = { age:1, name:'w' } ~~~ * ts 提供的只讀 和可選 映射方法使用 ~~~ interface Info1 { age: number; name: string; } // 都是只讀 const infos3:Readonly<Info1> = { age:1, name:'w' } // 都是可選 const infos4: Partial<Info1> = { age: 1, name: 'w' } ~~~ * ts 提供的選擇方法 ~~~ // 這里要注意可選是要填兩個位置 interface Info { name:string, age:number, address:string } // 只使用 name 和age 字段 const a:Pick<Info,'name'|'age'> = { name:'w', age:12 } // 當方法需要返回是一個對象時候 const info5 = { name: 'lison', age: 18, address: 'beijing', } // 返回的是一個對象 用pick 來做了指定 function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> { const res: any = {} keys.map((key) => { res[key] = obj[key] }) return res } const nameAndAddress = pick(info5, ['name', 'address']) console.log(nameAndAddress) ~~~ * ts Record 記錄 * 常見不規范的錯 ~~~ // 錯誤用有時候工作,定義了一個對象類型賦值是一個object // object 沒有foo字段會報錯 // let bb: object ={ // foo:'s' // } // bb.foo; // k 為任意類型 ,value 為任意類型,解決 let aa: Record<any, any>={ foo:'w' } aa.foo ~~~ * 注意Record兩個參數指定的都是類型 ~~~ interface Info { name:string, age:number } // 定義的a key 是Info 接口Key類型,value 是string類型 const a:Record<Info[keyof Info],string> = { name:'w', age:'w' } ~~~ * 一個函數使用小案例 ~~~ function mapObject<K extends string | number, T, U>(obj: Record<K, T>, f: (x: T) => U): Record<K, U> { const res: any = {} for (const key in obj) { res[key] = f(obj[key]) } return res } const names = { 0: 'hello', 1: 'world', 2: 'bye' } const lengths = mapObject(names, (s) => s.length) console.log(lengths) ~~~ * 其他的映射方法 ~~~ // infer 推到 type Type8<T> = T extends any[] ? T[number] : T type Test3 = Type8<string[]> type Test4 = Type8<string> type Type9<T> = T extends Array<infer U> ? U : T type Test5 = Type9<string[]> // type Test5 = string 如果是數組取得是數組向中的值 type Test6 = Type9<string> // type Test6 = string // Exclude<T, U> type Type10 = Exclude<'a' | 'b' | 'c', 'a'> // type Type10 = "b" | "c" 排除 a // Extract<T, U> type Type11 = Extract<'a' | 'b' | 'c', 'c' | 'b'|'f'> // type Type11 = "b" | "c" 取兩者的交集 // NonNullable<T> type Type12 = NonNullable<string | number | null | undefined> // type Type12 = string | number 排除null 和undefined // ReturnType<T> type Type13 = ReturnType<() => string> // type Type13 = string 將方法返回值作為類型 type Type14 = ReturnType<() => void> // type Type14 = void // InstanceType<T> // 有就是他的構造函數類型沒有就是any class AClass { constructor() {} public sum(){} } class BClass { constructor() {} public sum(){} } class DClass { constructor() {} } type T1 = InstanceType<typeof AClass> type T2 = InstanceType<any> type T3 = InstanceType<never> // type T4 = InstanceType<string> // const t1: T1 = new DClass() // 報錯 const t2: T1 = new BClass() const t3: T1 = new AClass() const t4: T1 = {sum(){}} ~~~ >[danger] ##### 由映射類型進行推斷 ? 這里暫時不懂 ~~~ type Proxy<T> = { get(): T; set(value: T): void; } type Proxify<T> = { [P in keyof T]: Proxy<T[P]> } function proxify<T>(obj: T): Proxify<T> { const result = {} as Proxify<T> for (const key in obj) { result[key] = { get: () => obj[key], set: (value) => obj[key] = value, } } return result } let props = { name: 'lison', age: 18, } let proxyProps = proxify(props) proxyProps.name.set('li') // console.log(proxyProps.name.get()) // -------------- 揭開包裝類型----------------- function unproxify<T>(t: Proxify<T>): T { const result = {} as T for (const k in t) { result[k] = t[k].get() } return result } let originalProps = unproxify(proxyProps) ~~~ >[danger] ##### 移除特定修飾符 -- 用'-' 來移除 ~~~ // 移除特定修飾符 readonly 和 ?可以選 interface A { readonly name:string; readonly age:number; } type RemoveA<T> = { -readonly [P in keyof T]-?:T[P] } ~~~ >[danger] ##### 不要思維定式 ~~~ type Tuple = [number, string, boolean] type promiseTuple = MapToPromise<Tuple> let tuple1: promiseTuple = [ new Promise((resolve, reject) => resolve(1)), new Promise((resolve, reject) => resolve('a')), new Promise((resolve, reject) => resolve(false)), ] ~~~ >[danger] ##### unknown ~~~ 1.TypeScript 3.0 引入了新的unknown 類型,它是 any 類型對應的安全類型。 2.unknown 和 any 的主要區別是 unknown 類型會更加嚴格:在對 unknown 類型的值執行大多數操作之前, 我們必須進行某種形式的檢查。而在對 any 類型的值執行操作之前,我們不必進行任何檢查。 3.使用any類型,可以很容易地編寫類型正確但是執行異常的代碼。如果我們使用 any 類型, 就無法享受 TypeScript 大量的保護機制。但如果能有頂級類型也能默認保持安全呢?這就是 unknown 到來的原因 ~~~ ~~~ // unknown // [1] 任何類型都可以賦值給unknown類型 let value1: unknown value1 = 'a' value1 = 123 // [2] 如果沒有類型斷言或基于控制流的類型細化時,unknown不可以賦值給其他類型,此時他只能賦值給unknown和any類型 let value2: unknown // let value3: string = value2 // 因為value3 是string類型所以 value2不能賦值給value3 value1 = value2 // 可以賦值給any 和unkown 類型 // [3] 如果沒有類型斷言或基于控制流的類型細化時,不能在他上面進行任何操作 let value4: unknown // value4 += 1 // 沒有給具體指定 因此+=1 報錯 // [4] unknown與任何其他類型組成的交叉類型,最后都等于其他類型 type type1 = string & unknown // string type type2 = number & unknown // number type type3 = unknown & unknown // unknown type type4 = unknown & string[] // string[] // [5] unknown與任何其他類型(除了any是any)組成的聯合類型,都等于unknown類型 type type5 = unknown | string // unknown type type6 = any | unknown // any type type7 = number[] | unknown // unknown // [6] never類型是unknown的子類型 type type8 = never extends unknown ? true : false // [7] keyof unknown 等于類型never type type9 = keyof unknown // never // [8] 只能對unknown進行等或不等操作,不能進行其他操作 // value1 === value2 // value1 !== value2 // value1 += value2 // [9] unknown類型的值不能訪問他的屬性、作為函數調用和作為類創建實例 let value10: unknown // value10.age // value10() // new value10() // [10] 使用映射類型時如果遍歷的是unknown類型,則不會映射任何屬性 type Types1<T> = { [P in keyof T]: number } type type11 = Types1<any> // type type11 = {[x: string]: number;} type type12 = Types1<unknown> // type type12 = {} ~~~ >[danger] ##### 條件類型 ~~~ 1.向三運運算動態指定類型 ~~~ ~~~ // T extends U ? X : Y type Types2<T> = T extends string ? string : number // let index: Types2<false> // type TypeName<T> = T extends any ? T : never // type Type3 = TypeName<string | number> type TypeName<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T extends undefined ? undefined : T extends () => void ? () => void : object type Type4 = TypeName<() => void> type Type5 = TypeName<string[]> type Type6 = TypeName<(() => void) | string[]> type Diff<T, U> = T extends U ? never : T type Test2 = Diff<string | number | boolean, undefined | number> // keyof T 排除never 類型 type Type7<T> = { [K in keyof T]: T[K] extends Function ? K : never }[keyof T] interface Part { id: number; name: string; subparts: Part[]; undatePart(newName: string): void } type Test1 = Type7<Part> ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看