摘要:版本記錄針對(duì)版本的特性作專(zhuān)門(mén)的實(shí)例,希望能加深理解。這種情況下添加類(lèi)型屬性被間接初始化了例如構(gòu)造函數(shù)中調(diào)用一個(gè)方法,更改了屬性的值。這種情況下我們可以使用顯式賦值斷言修飾符號(hào)來(lái)幫助類(lèi)型系統(tǒng)識(shí)別類(lèi)型。
TypeScript 2.7版本記錄
針對(duì)ts 2.7版本的特性作專(zhuān)門(mén)的實(shí)例,希望能加深理解。實(shí)例github地址 官方日志文檔增加常量聲明的屬性的支持(Constant-named properties) 對(duì)于常量,有更加智能的提示
const Foo = "Foo"; const Bar = "Bar"; let x = { // 2.7版本之前,x的類(lèi)型為{[x:string]:string|number},現(xiàn)在為 {[Foo]: number;[Bar]: string;}} [Foo]: 100, [Bar]: "hello", }; let a = x[Foo]; // has type "number" let b = x[Bar]; // has type "string"typescript 增加一種新的類(lèi)型聲明:unique symbols,是 symbols的子類(lèi)型,僅可通過(guò)調(diào)用 Symbol()或 Symbol.for()或由明確的類(lèi)型注釋生成
ES6 引入的 Symbol 機(jī)制,Symbol是js的第七種數(shù)據(jù)類(lèi)型,可以產(chǎn)生獨(dú)一無(wú)二的值,可以用來(lái)保證每個(gè)屬性的名字都是獨(dú)一無(wú)二,從根本上防止屬性名的沖突。結(jié)合ts,我們可以這樣聲明一個(gè)symbol,const Foo: unique symbol = Symbol()
unique symbol 類(lèi)型必須由 const 關(guān)鍵字聲明
// Error! "Bar" isn"t a constant. let Bar: unique symbol = Symbol();
引用賦值一個(gè) unique symbol 類(lèi)型的值時(shí)候使用 typeof 操作符
// let Baz = Foo // 這樣的話(huà) Baz 的類(lèi)型為symbol let Baz: typeof Foo = Foo // 類(lèi)型為unique symbol // 在class里面使用 `unique symbol` 定義類(lèi)的靜態(tài)屬性(不能用在類(lèi)屬性) 時(shí), // 需要使用 `readonly static` 關(guān)鍵字來(lái)聲明 class C { static readonly StaticSymbol: unique symbol = Symbol(); }
當(dāng)Symbol + const時(shí),值的類(lèi)型自動(dòng)判斷為unique symbol
// let SERIALIZE = Symbol("serialize-method-key"); SERIALIZE 類(lèi)型為symbol const SERIALIZE = Symbol("serialize-method-key"); // SERIALIZE 類(lèi)型為unique symbol
接口中的計(jì)算屬性名稱(chēng)引用必須引用類(lèi)型為文本類(lèi)型或 "unique symbol"
interface Serializable { // [("serialize-method-key")](obj: {}): string; //error [SERIALIZE](obj: {}): string; } class JSONSerializableItem implements Serializable { // error 只能用引入的SERIALIZE來(lái)作屬性的名稱(chēng) // ["serialize-method-key"](obj: {}) { // return JSON.stringify(obj); // } [SERIALIZE](obj: {}) { return JSON.stringify(obj); } }
另外,兩個(gè)unique symbol類(lèi)型的值不能互相比較(當(dāng)然除非其中一個(gè)值的類(lèi)型為用 typeof 另外一個(gè)值)
新編譯選項(xiàng),更嚴(yán)格的類(lèi)屬性檢查( --strictPropertyInitialization)TypeScript 2.7引入了一個(gè)新的控制嚴(yán)格性的標(biāo)記 --strictPropertyInitialization
現(xiàn)在,如果開(kāi)啟 strictPropertyInitialization,我們必須要確保每個(gè)實(shí)例的屬性都會(huì)初始值,可以在構(gòu)造函數(shù)里或者屬性定義時(shí)賦值。
class StrictClass { foo: number; bar = "hello"; baz: boolean; // error,Property "baz" has no initializer and is not definitely assigned in the constructor constructor() { this.foo = 42; } }
有兩種情況下我們不可避免該error的產(chǎn)生:
該屬性本來(lái)就可以是 undefined 。這種情況下添加類(lèi)型undefined
屬性被間接初始化了(例如構(gòu)造函數(shù)中調(diào)用一個(gè)方法,更改了屬性的值)。這種情況下我們可以使用 顯式賦值斷言 (修飾符號(hào) !) 來(lái)幫助類(lèi)型系統(tǒng)識(shí)別類(lèi)型。后面具體介紹它,先看下代碼中怎么使用:
class StrictClass { // ... baz!: boolean; // ^ // 注意到這個(gè)!標(biāo)志 // 代表著顯式賦值斷言修飾符 }顯式賦值斷言(Definite Assignment Assertions)
盡管我們嘗試將類(lèi)型系統(tǒng)做的更富表現(xiàn)力,但我們知道有時(shí)用戶(hù)比TypeScript更加了解類(lèi)型
跟上面提到的類(lèi)屬性例子差不多,我們無(wú)法在給一個(gè)值賦值前使用它,但如果我們已經(jīng)確定它已經(jīng)被賦值了,這個(gè)時(shí)候類(lèi)型系統(tǒng)就需要我們?nèi)说慕槿?/p>
let x: number; initialize(); console.log(x + x); // ~ ~ // Error! Variable "x" is used before being assigned. function initialize() { x = 10; }
添加 ! 修飾:let x!: number,則可以修復(fù)這個(gè)問(wèn)題
我們也可以在表達(dá)式中使用!,類(lèi)似 variable as string和
let x: number; initialize(); console.log(x! + x!); //ok function initialize() { x = 10; }添加 --esModuleInterop 對(duì)ES模塊和老式代碼更好的互通
這一塊中文官網(wǎng)花了挺長(zhǎng)篇幅來(lái)講這個(gè)內(nèi)容,我也是實(shí)踐過(guò)才明白講的是什么,需要理解 __esModule 標(biāo)記是做什么的、es6模塊經(jīng)過(guò)ts轉(zhuǎn)換成commonjs是怎么的、 如何保持與老式代碼( CommonJS/AMD/UMD)的互通性
先說(shuō)一下 --esModuleInterop 的作用:
默認(rèn)開(kāi)啟allowSyntheticDefaultImports(那是肯定的,我們需要它來(lái)實(shí)現(xiàn)默認(rèn)導(dǎo)入的功能)
命名空間導(dǎo)入不允許被調(diào)用或者構(gòu)造,需要改成默認(rèn)導(dǎo)入
import * as express from "express"; // error 正確的實(shí)現(xiàn)導(dǎo)入方式應(yīng)該是下面這種 import express from "express"; express();
注意: 我們強(qiáng)烈建議開(kāi)啟esModuleInterop,不管在新代碼或者是老代碼上。但該模式下會(huì)可能對(duì)已有的代碼產(chǎn)生破環(huán),對(duì)已有的命名空間導(dǎo)入(import * as express from "express"; express();)改成默認(rèn)導(dǎo)入(import express from "express"; express(); )
讓我們更深入理解,在 --esModuleInterop 下,ts對(duì) import * 和 import default兩種導(dǎo)入方式用兩個(gè)helpers __importStar and __importDefault做分別處理。
構(gòu)建前的代碼:
import * as foo from "foo"; import b from "bar"; const a = "newM" export default a
構(gòu)建后的代碼:
"use strict"; var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; result["default"] = mod; return result; } var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; } exports.__esModule = true; var foo = __importStar(require("foo")); var bar_1 = __importDefault(require("bar")); const a = "newM"; exports.default = a;
這樣做的結(jié)果是,我們新的代碼不管是通過(guò)ts,Babel或Webpack來(lái)構(gòu)建,都能通過(guò) __esModule 來(lái)判斷是否為es模塊,如果無(wú)__esModule,則創(chuàng)建含default的對(duì)象保存模塊,這樣就完成我們要的默認(rèn)導(dǎo)入功能,同時(shí)保持對(duì)老的庫(kù)的支持
固定長(zhǎng)度元祖[number, string, string]類(lèi)型的值 不可賦值 [number, string] 類(lèi)型的值了。
[number, string]類(lèi)型等同于下面的 NumStrTuple聲明:
interface NumStrTuple extends Array{ 0: number; 1: string; length: 2; // using the numeric literal type "2" }
NumStrTuple 代表類(lèi)型為固定長(zhǎng)度為2,[0]為number類(lèi)型,[1]為string 類(lèi)型的數(shù)組
如果不希望固定寬度,只需要最小長(zhǎng)度,可以這樣:
interface MinimumNumStrTuple extends Array更智能的對(duì)象字面量推斷{ 0: number; 1: string; }
// 現(xiàn)在能正常判斷obj的類(lèi)型了,而不是之前的 {} const obj = test ? { text: "hello" } : {}; // { text: string } | { text?: undefined } const s = obj.text; // string | undefined // { a: number, b: number } | // { a: string, b?: undefined } | // { a?: undefined, b?: undefined } let obj2 = [{ a: 1, b: 2 }, { a: "abc" }, {}][0]; declare function f其它 in操作符細(xì)化和精確的 instanceof(...items: T[]): T; // { a: number, b: number } | // { a: string, b?: undefined } | // { a?: undefined, b?: undefined } let obj3 = f({ a: 1, b: 2 }, { a: "abc" }, {});
in 操作符 和 instanceof 運(yùn)算符 更好用了(就是那么簡(jiǎn)單)
--watch,--pretty 編譯--watch 會(huì)在重新編譯后清空控制臺(tái)
--pretty 更好地展示錯(cuò)誤信息
看圖:
完。參考:ts官方
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/95072.html
摘要:怎么影響了我的思考方式對(duì)前端開(kāi)發(fā)者來(lái)說(shuō),能強(qiáng)化了面向接口編程這一理念。使用的過(guò)程就是在加深理解的過(guò)程,確實(shí)面向接口編程天然和靜態(tài)類(lèi)型更為親密。摘要: 學(xué)會(huì)TS思考方式。 原文:TypeScript - 一種思維方式 作者:zhangwang Fundebug經(jīng)授權(quán)轉(zhuǎn)載,版權(quán)歸原作者所有。 電影《降臨》中有一個(gè)觀點(diǎn),語(yǔ)言會(huì)影響人的思維方式,對(duì)于前端工程師來(lái)說(shuō),使用 typescript 開(kāi)...
摘要:比如或者都會(huì)導(dǎo)致函數(shù)返回值類(lèi)型時(shí)。和特性一樣,等于是函數(shù)返回值中的或。注意對(duì)比下面的寫(xiě)法對(duì)于,它的返回值是可迭代的對(duì)象,并且每個(gè)類(lèi)型都是或者。首先是不支持方法重載的,是支持的,而類(lèi)型系統(tǒng)一定程度在對(duì)標(biāo),當(dāng)然要支持這個(gè)功能。 1 引言 精讀原文是 typescript 2.0-2.9 的文檔: 2.0-2.8,2.9 草案. 我發(fā)現(xiàn),許多寫(xiě)了一年以上 Typescript 開(kāi)發(fā)者,對(duì) T...
摘要:在該版本發(fā)布之后,開(kāi)發(fā)團(tuán)隊(duì)并不會(huì)繼續(xù)發(fā)布新的特性,而會(huì)著眼于進(jìn)行重大的錯(cuò)誤修復(fù)。發(fā)布每六個(gè)星期,團(tuán)隊(duì)就會(huì)創(chuàng)建新的分支作為發(fā)布通道,本文即是對(duì)新近發(fā)布的版本進(jìn)行簡(jiǎn)要介紹。 showImg(https://segmentfault.com/img/remote/1460000013229009); 前端每周清單專(zhuān)注前端領(lǐng)域內(nèi)容,以對(duì)外文資料的搜集為主,幫助開(kāi)發(fā)者了解一周前端熱點(diǎn);分為新聞熱...
摘要:基于的版本和編寫(xiě)的模仿原生應(yīng)用的源碼地址歡迎項(xiàng)目演示地址建議直接添加到主屏幕端體驗(yàn)差一些前言為什么做這個(gè)項(xiàng)目學(xué)習(xí)全家桶,很長(zhǎng)一段時(shí)間在用。作者聲稱(chēng)之后增強(qiáng)了對(duì)的支持,探究在中的支持情況。 vue-ts-daily 基于Vue.js的2.5.13版本和TypeScript編寫(xiě)的模仿原生應(yīng)用的WebApp.源碼地址 歡迎star 項(xiàng)目演示地址 showImg(https://segment...
摘要:于是搜了下原因,原來(lái)是創(chuàng)建時(shí)候的默認(rèn)源配置導(dǎo)致,安裝報(bào)錯(cuò)問(wèn)題解決所以修改下剛才生成的下的屬性值為就可以了再次安裝成功原文 使用最新的Vue CLI @vue/cli創(chuàng)建typescript項(xiàng)目,使用vue -V查看當(dāng)前的vue cli版本 安裝命令 npm install -g @vue-cli 創(chuàng)建項(xiàng)目 vue create my-vue-typescript showImg(htt...
閱讀 2418·2021-11-25 09:43
閱讀 1250·2021-11-24 09:39
閱讀 752·2021-11-23 09:51
閱讀 2389·2021-09-07 10:18
閱讀 1867·2021-09-01 11:39
閱讀 2783·2019-08-30 15:52
閱讀 2598·2019-08-30 14:21
閱讀 2863·2019-08-29 16:57