typescript 怎么表示当前时间减一个月_TypeScript 入门知识点总结
TypeScript 介紹
什么是 TypeScript
是 JavaScript 的一個(gè)超集,它可以編譯成純 JavaScript。編譯出來(lái)的 JavaScript 可以運(yùn)行在任何瀏覽器上,主要提供了「類型系統(tǒng)」和「對(duì) ES6 的支持」。
為什么選擇 TypeScript
- 增加了代碼的可維護(hù)性
- 包容性強(qiáng),支持 ES6 語(yǔ)法,.js文件直接重命名為.ts即可
- 兼容第三方庫(kù),即使第三方庫(kù)不是 TypeScript 寫的,也可以通過(guò)單獨(dú)編寫類型文件供識(shí)別讀取
- 社區(qū)活躍,目前三大框架還有越來(lái)越多的庫(kù)都支持 TypeScript 了
TypeScript 只會(huì)在編譯的時(shí)候?qū)︻愋瓦M(jìn)行靜態(tài)檢查,如果發(fā)現(xiàn)有錯(cuò)誤,編譯的時(shí)候就會(huì)報(bào)錯(cuò)。
安裝 TypeScript
我當(dāng)前版本為 Version 4.0.2
"rootDir":?"./src"
之后你寫的 ts 文件編譯錯(cuò)誤都會(huì)直接提示,如果想運(yùn)行文件,就到 /dist目錄下找相應(yīng)的 js 文件,使用 node 運(yùn)行即可
ts-node 安裝
當(dāng)然這樣其實(shí)也挺麻煩,我們想直接運(yùn)行 TS 文件, 這時(shí)可以借助ts-node插件
全局安裝
npm?install?-g?ts-node找到文件路徑,運(yùn)行即可
ts-node?demo.ts基礎(chǔ)類型
Number 類型
let?num:?number?=?2Boolean 類型
let?isShow:?boolean?=?trueString 類型
let?str:?string?=?'hello'Array 類型
let?arr1:?number[]?=?[1,?2,?3]let?arr2:?Array<number>?=?[2,?3,?4]
Any 類型
let?foo:?any?=?'hello'foo?=?12
foo?=?false
Null 和 Undefined 類型
null 和 undefined 可以賦值給任意類型的變量
let?test1:?undefined?=?undefinedlet?test2:?null?=?null
let?test3:?number
let?test4:?string
test3?=?null
test4?=?undefined
Void 類型
void 類型像是與 any 類型相反,它表示沒(méi)有任何類型。當(dāng)一個(gè)函數(shù)沒(méi)有返回值時(shí),其返回值類型是 void
let?test5:?void?=?undefined?//?聲明一個(gè)?void?類型的變量沒(méi)有什么用,因?yàn)樗闹抵荒転?undefined?或?nullfunction?testFunc():?void?{}?//?函數(shù)沒(méi)有返回值
Never 類型
never 類型表示的是那些永不存在的值的類型。
function?bar():?never?{??throw?new?Error('never?reach')
}
Unknown 類型
所有類型都可以賦值給 any,所有類型也都可以賦值給 unknown。
let?value:?unknownvalue?=?123
value?=?'Hello'
value?=?true
let?value1:?unknown?=?value
let?value2:?any?=?value
let?value3:?boolean?=?value?//?Error
let?value4:?number?=?value?//?Error
let?value5:?string?=?value?//?Error
let?value6:?object?=?value?//?Error
let?value7:?any[]?=?value?//?Error
let?value8:?Function?=?value?//?Error
unknown 類型只能被賦值給 any 類型和 unknown 類型本身。
Tuple 類型
數(shù)組合并了相同類型的對(duì)象,而元組(Tuple)合并了不同類型的對(duì)象。元組表示一個(gè)數(shù)量和類型都已知的數(shù)組
let?tupleArr1:?[string,?number]?=?['hello',?10]//?let?tupleArr2:?[string,?number]?=?[10,?'hello']?//?Error
Enum 類型
使用枚舉可以定義一些帶名字的常量。TypeScript 支持?jǐn)?shù)字的和基于字符串的枚舉。
??enum?Season?{????Spring,
????Summer,
????Autumn,
????Winter,
??}
??let?a:?Season?=?Season.Spring
??let?b:?Season?=?Season.Summer
??let?c:?Season?=?Season.Autumn
??let?d:?Season?=?Season.Winter
??console.log(a,?b,?c,?d)?//?0?1?2?3
}
函數(shù)類型
函數(shù)聲明
//?JSfunction?func1(x,?y)?{
??return?x?+?y
}
//?TS
function?func2(x:?number,?y:?number):?number?{
??return?x?+?y
}
函數(shù)表達(dá)式
在 TypeScript 的類型定義中,=> 用來(lái)表示函數(shù)的定義,左邊是輸入類型,需要用括號(hào)括起來(lái),右邊是輸出類型。
//?JSlet?func3?=?function?(x,?y)?{
??return?x?+?y
}
//?TS?第一種方式
let?func4?=?function?(x:?number,?y:?number):?number?{
??return?x?+?y
}
//?TS?第二種方式
//?=>?用來(lái)表示函數(shù)的定義,左邊是輸入類型,需要用括號(hào)括起來(lái),右邊是輸出類型。
let?func5:?(x:?number,?y:?number)?=>?number?=?function?(x:?number,?y:?number):?number?{
??return?x?+?y
}
接口定義函數(shù)的形狀
采用函數(shù)表達(dá)式|接口定義函數(shù)的方式時(shí),對(duì)等號(hào)左側(cè)進(jìn)行類型限制,可以保證以后對(duì)函數(shù)名賦值時(shí)保證參數(shù)個(gè)數(shù)、參數(shù)類型、返回值類型不變。
interface?SearchFunc?{??(source:?string,?subString:?string):?boolean
}
let?mySearch:?SearchFunc
mySearch?=?function?(source:?string,?subString:?string)?{
??return?source.search(subString)?!==?-1
}
可選參數(shù)
對(duì)于 TS 的函數(shù),輸入多余的(或者少于要求的)參數(shù),是不允許的,那么該怎么設(shè)置可選參數(shù)呢?,我們可以在聲明之后加一個(gè)問(wèn)號(hào)
function?getName1(firstName:?string,?lastName?:?string)?{??//?可選參數(shù)必須接在必需參數(shù)后面
??if?(lastName)?{
????return?`${firstName}?${lastName}`
??}?else?{
????return?firstName
??}
}
let?name1?=?getName1('jacky')
let?name2?=?getName1('jacky',?'lin')
console.log(name1,?name2)
參數(shù)默認(rèn)值
function?getName2(firstName:?string?=?'monkey',?lastName:?string)?{??return?`${firstName}?${lastName}`
}
console.log(getName2('jacky',?'Lin'))
console.log(getName2(undefined,?'Lin'))?//?monkey?Lin
void 和 never 類型
當(dāng)函數(shù)沒(méi)有返回值時(shí),可以用 void 來(lái)表示。
當(dāng)一個(gè)函數(shù)永遠(yuǎn)不會(huì)返回時(shí),我們可以聲明返回值類型為 never
function?func6():?void?{??//?return?null
}
function?func7():?never?{
??throw?new?Error('never?reach')
}
剩余參數(shù)
function?push1(arr,?...items)?{??items.forEach(function?(item)?{
????arr.push(item)
??})
}
let?a:?any[]?=?[]
push1(a,?1,?2,?3)
function?push2(arr:?any[],?...items:?any[]):?void?{
??items.forEach(function?(item)?{
????arr.push(item)
??})
}
let?b:?any[]?=?[]
push1(b,?1,?2,?3,?'5')
函數(shù)參數(shù)為對(duì)象(解構(gòu))時(shí)
//?js寫法function?add({?one,?two?})?{
??return?one?+?two
}
const?total?=?add({?one:?1,?two:?2?})
//?ts?寫法
function?add1({?one,?two?}:?{?one:?number;?two:?number?}):?number?{
??return?one?+?two
}
const?three?=?add1({?one:?1,?two:?2?})
函數(shù)重載
重載允許一個(gè)函數(shù)接受不同數(shù)量或類型的參數(shù)時(shí),作出不同的處理。
function?reverse(x:?number):?number?//?函數(shù)定義function?reverse(x:?string):?string?//?函數(shù)定義function?reverse(x:?number?|?string):?number?|?string?{??//?函數(shù)實(shí)現(xiàn)if?(typeof?x?===?'number')?{return?Number(x.toString().split('').reverse().join(''))
??}?else?if?(typeof?x?===?'string')?{
????return?x.split('').reverse().join('')
??}
}
類型斷言
TypeScript 允許你覆蓋它的推斷,并且能以你任何你想要的方式分析它,這種機(jī)制被稱為「類型斷言」。
TypeScript 類型斷言用來(lái)告訴編譯器你比它更了解這個(gè)類型,你知道你自己在干什么,并且它不應(yīng)該再發(fā)出錯(cuò)誤。
interface?Cat?{??name:?string
??run():?void
}
interface?Fish?{
??name:?string
??swim():?void
}
//?只能訪問(wèn)共有的屬性
function?getName(animal:?Cat?|?Fish):?string?{
??return?animal.name
}
//?將?animal?斷言成?Fish?就可以解決訪問(wèn)?animal.swim?時(shí)報(bào)錯(cuò)的問(wèn)題
function?isFish(animal:?Cat?|?Fish):?boolean?{
??if?(typeof?(animal?as?Fish).swim?===?'function')?{
????return?true
??}
??return?false
}
//?任何類型都可以被斷言為?any
;(window?as?any).randomFoo?=?1
//?類型斷言第一種方式:"尖括號(hào)"語(yǔ)法
let?value1:?any?=?'hello'
let?value1Length:?number?=?(<string>value1).length
//?類型斷言第二種方式:as
let?value2:?any?=?'world'
let?value2Length:?number?=?(value2?as?string).length
類
存取器
class?Animal?{??constructor(name:?string)?{
????this.name?=?name
??}
??//?getter
??get?name()?{
????return?'名字'
??}
??//?setter
??set?name(value:?string)?{
????console.log('setter:?'?+?value)
??}
}
let?animal?=?new?Animal('monkey')
console.log(animal.name)?//?monkey
animal.name?=?'mk'?//?setter:?mk
訪問(wèn)修飾符
- public 修飾的屬性或方法是公有的,可以在任何地方被訪問(wèn)到,默認(rèn)所有的屬性和方法都是 public 的
- private 修飾的屬性或方法是私有的,不能在聲明它的類的外部訪問(wèn)
- protected 修飾的屬性或方法是受保護(hù)的,它和 private 類似,區(qū)別是它在子類中也是允許被訪問(wèn)的
??public?name
??private?age
??protected?sex
??public?constructor(name:?string,?age:?number,?sex:?string)?{
????this.name?=?name
????this.age?=?age
????this.sex?=?sex
??}
}
let?person1?=?new?Person('jacky',?22,?'man')
person1.name?=?'monkey'?//?name值可以訪問(wèn)且修改
//?person1.age?//?Property?'age'?is?private?and?only?accessible?within?class?'Person'.
//?person1.sex?//?Property?'sex'?is?private?and?only?accessible?within?class?'Person'.
class?Person1?extends?Person?{
??constructor(name:?string,?age:?number,?sex:?string)?{
????super(name,?age,?sex)
????//?console.log(this.name,?this.age,?this.sex)?//?Property?'age'?is?private?and?only?accessible?within?class?'Person'.
??}
}
參數(shù)屬性
同時(shí)給類中定義屬性的同時(shí)賦值
class?Animal3?{??public?name
??constructor(name:?string)?{
????this.name?=?name
??}
}
console.log(new?Animal3('animal3').name)?//?animal3
class?Animal2?{
??constructor(public?name:?string)?{}?//?簡(jiǎn)潔形式
}
console.log(new?Animal2('animal2').name)?//?animal2
- readonly 只讀屬性
??readonly?name
??constructor(name:?string)?{
????this.name?=?name
??}
}
let?animal4?=?new?Animal4('animal4')
//?animal4.name?=?'5'?//?Cannot?assign?to?'name'?because?it?is?a?read-only?property
抽象類
//?抽象類是行為的抽象,一般來(lái)封裝公共屬性的方法的,不能被實(shí)例化abstract?class?CommonAnimal?{
??name:?string
??abstract?speak():?void
}
static
class?Animal5?{??static?sayHi()?{
????console.log('Hello?Animal5')
??}
}
Animal5.sayHi()
聯(lián)合類型
聯(lián)合類型(Union Types)表示取值可以為多種類型中的一種。使用一個(gè)|分割符來(lái)分割多種類型
let?foo:?string?|?number?|?booleanfoo?=?'test'
foo?=?3
foo?=?true
交叉類型
interface?IPerson?{??id:?string
??age:?number
}
interface?IWorker?{
??companyId:?string
}
type?IStaff?=?IPerson?&?IWorker
const?staff:?IStaff?=?{?id:?'007',?age:?24,?companyId:?'1'?}
類型別名
type?Message?=?string?|?string[]let?getMsg?=?(message:?Message)?=>?{
??return?message
}
type?Weather?=?'SPRING'?|?'SUMMER'?|?'AUTUMN'?|?'WINTER'
let?weather1:?Weather?=?'SPRING'
let?weather2:?Weather?=?'AUTUMN'
接口
對(duì)象的形狀
interface?Person1?{??name:?string
??age:?number
}
let?person1:?Person1?=?{
??name:?'jacky',
??age:?23,
}
描述行為的抽象
interface?AnimalLike?{??eat():?void
??move():?void
}
interface?PersonLike?extends?AnimalLike?{
??speak():?void
}
class?Human?implements?PersonLike?{
??speak()?{}
??eat()?{}
??move()?{}
}
含構(gòu)建函數(shù)作參數(shù)的寫法
class?Animal1?{??constructor(public?name:?string)?{}
??age:?number
}
class?Animal2?{
??constructor(public?age:?number)?{}
}
interface?WithNameClass?{
??new?(name:?string):?Animal1
}
function?createClass(classname:?WithNameClass,?name:?string)?{
??return?new?classname(name)
}
let?instance1?=?createClass(Animal1,?'monkey')
//?let?instance2?=?createClass(Animal2,?'monkey')?//?沒(méi)有name屬性則報(bào)錯(cuò)
其它任意屬性
interface?Person2?{??readonly?id:?number
??[propName:?string]:?any?//任意屬性
}
泛型
泛型是指定義函數(shù)、接口或類的時(shí)候,不預(yù)先指定具體的類型,而在使用的時(shí)候再指定類型的一種特性;通常用 T 表示,但不是必須使用改字母,只是常規(guī),通常還有其他常用字母:
- T(Type):表示一個(gè) TypeScript 類型
- K(Key):表示對(duì)象中的鍵類型
- V(Value):表示對(duì)象中的值類型
- E(Element):表示元素類型
泛型類
class?GenericNumber?{??name:?T
??add:?(x:?T,?y:?T)?=>?T
}let?generic?=?new?GenericNumber<number>()
generic.name?=?123
泛型數(shù)組
- 寫法一
??return?params
}
func<string>(['1',?'2'])
func<number>([1,?2])
- 寫法二
??return?params
}
func1<string>(['1',?'2'])
func1<number>([1,?2])
泛型接口
可以用來(lái)約束函數(shù)
interface?Cart?{??list:?T[]
}let?cart:?Cart<number>?=?{?list:?[1,?2,?3]?}
泛型別名
type?Cart2?=?{?list:?T[]?}?|?T[]let?c1:?Cart2<number>?=?{?list:?[1,?2,?3]?}let?c2:?Cart2<number>?=?[1,?2,?3]泛型接口 VS 泛型別名
- 接口創(chuàng)建了一個(gè)新的名字,它可以在其他任意地方被調(diào)用。而類型別名并不創(chuàng)建新的名字
- 類型別名不能被 extends 和 implements,這時(shí)我們應(yīng)該盡量使用接口代替類型別名
- 當(dāng)我們需要使用聯(lián)合類型或者元組類型的時(shí)候,類型別名會(huì)更合適
多個(gè)泛型
//?不借助中間變量交換兩個(gè)變量的值function?swap<T,?P>(tuple:?[T,?P]):?[P,?T]?{
??return?[tuple[1],?tuple[0]]
}
let?ret?=?swap([1,?'a'])
ret[0].toLowerCase()
ret[1].toFixed(2)
默認(rèn)泛型
function?createArray<T?=?number>(length:?number,?value:?T):?T[]?{??let?arr:?T[]?=?[]
??for?(let?i?=?0;?i?????arr[i]?=?value
??}
??return?arr
}
let?arr?=?createArray(3,?9)
泛型約束(繼承)
interface?WithLength?{??length:?number
}
//?extends?來(lái)繼承
function?logger<T?extends?WithLength>(val:?T)?{
??console.log(val.length)
}
logger('hello')
logger([1,?2,?3])
//?logger(true)?//?error?沒(méi)有l(wèi)ength屬性
泛型工具類型
為了方便開(kāi)發(fā)者 TypeScript 內(nèi)置了一些常用的工具類型,比如 Partial、Required、Readonly、Pick 等。它們都是使用 keyof 實(shí)現(xiàn)。
keyof 操作符可以用來(lái)一個(gè)對(duì)象中的所有 key 值。
interface?Person1?{??name:?string
??age:?number
??sex?:?string
}
type?PersonKey?=?keyof?Person1?//?限制?key?值的取值
function?getValueByKey(p:?Person1,?key:?PersonKey)?{
??return?p[key]
}
內(nèi)置的工具類型
//?type?Partial?=?{[P?in?keyof?T]?:?T[P]}type?PersonSearch?=?Partial?//?全部變可選//?type?Required?=?{?[P?in?keyof?T]-?:?T[P]?}type?PersonRequired?=?Required?//?全部變必選//?type?ReadOnly?=?{?readonly?[P?in?keyof?T]:?T[P]?}type?PersonReadOnly?=?Readonly?//?全部變只讀//?type?Pick??=?{[P?in?K]:?T[P]}type?PersonSub?=?Pick'name'>?//?通過(guò)從Type中選擇屬性Keys的集合來(lái)構(gòu)造類型。
類數(shù)組
let?root?=?document.getElementById('root')let?children:?HTMLCollection?=?root!.children?//?!?代表非空斷言操作符
let?childNodes:?NodeListOf?=?root!.childNodes
類型保護(hù)
更明確的判斷某個(gè)分支作用域中的類型,主要嘗試檢測(cè)屬性、方法或原型,以確定如何處理值。
typeof
function?double(input:?string?|?number?|?boolean):?number?{??//?基本數(shù)據(jù)類型的類型保護(hù)
??if?(typeof?input?===?'string')?{
????return?input.length
??}?else?if?(typeof?input?===?'number')?{
????return?input
??}?else?{
????return?0
??}
}
instanceof
class?Monkey?{??climb:?string
}
class?Person?{
??sports:?string
}
function?getAnimalName(animal:?Monkey?|?Person)?{
??if?(animal?instanceof?Monkey)?{
????console.log(animal.climb)
??}?else?{
????console.log(animal.sports)
??}
}
in
class?Student?{??name:?string
??play:?string[]
}
class?Teacher?{
??name:?string
??teach:?string
}
type?SchoolRole?=?Student?|?Teacher
function?getRoleInformation(role:?SchoolRole)?{
??if?('play'?in?role)?{
????console.log(role.play)
??}
??if?('teach'?in?role)?{
????console.log(role.teach)
??}
}
自定義類型保護(hù)
比如有時(shí)兩個(gè)類型有不同的取值,也沒(méi)有其他可以區(qū)分的屬性
interface?Bird?{??leg:?number
}
interface?Dog?{
??leg:?number
}
function?isBird(x:?Bird?|?Dog):?x?is?Bird?{
??return?x.leg?===?2
}
function?getAnimal(x:?Bird?|?Dog):?string?{
??if?(isBird(x))?{
????return?'bird'
??}?else?{
????return?'dog'
??}
}
上述完整代碼示例:typescript-tutorial
?歡迎關(guān)注我掘金賬號(hào)和Github技術(shù)博客:
- 掘金:https://juejin.im/user/1257497033714477
- Github:https://github.com/Jacky-Summer
- 覺(jué)得對(duì)你有幫助或有啟發(fā)的話歡迎 star,你的鼓勵(lì)是我持續(xù)創(chuàng)作的動(dòng)力~
- 如需在微信公眾號(hào)平臺(tái)轉(zhuǎn)載請(qǐng)聯(lián)系作者授權(quán)同意,其它途徑轉(zhuǎn)載請(qǐng)?jiān)谖恼麻_(kāi)頭注明作者和文章出處。
總結(jié)
以上是生活随笔為你收集整理的typescript 怎么表示当前时间减一个月_TypeScript 入门知识点总结的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 如何在服务器上运行python程序_在服
- 下一篇: java文件共享ftp怎么访问_文件共享