TS演練場
使用export阻斷模塊
當只是單純的練習ts時如果在兩個ts文件中定義了相同的變量名這時就會報錯,因為這兩個ts文件屬于同一個作用域,因此可以使用export 導出一個空模塊來建立獨立的作用域
// index.ts
export {}
TS中的!和?用法
- 屬性或參數(shù)中使用 ?:表示該屬性或參數(shù)為可選項
- 屬性或參數(shù)中使用 ?。罕硎緩娭平馕?,告訴[typescript]編譯器,這里一定有值
- 變量后使用 !:表示類型推斷排除null、undefined
要支持ts解析!需要在tsconfig.json文件中配置
"compilerOptions": {
"suppressImplicitAnyIndexErrors": true,
}
TS中l(wèi)et 和 const 的區(qū)別
let定義變量它的類型可以根據(jù)變量的值自動推斷,const定義常量,但是const定義的常量的值就是它的類型
let num = 1 // TS會推斷出num的類型是number
const str = '123' // str的類型就是'123'
TS中object 和Object 的區(qū)別
object 是不包含原始類型的但是包含對象和數(shù)組,Object 是既包含原始類型也包含對象和數(shù)組,
{}和Object 是相同的
let obj :object = { a:' aa' }
let arr:object = [1,2,3]
let num:Object = 1
let obj:Object = {b: 'bb'}
let arr:Object = ['a', 'b']
ts中數(shù)組類型的定義
// 方法一
let arr: number[] = [1,2,3] // arr中的元素全為number類型
// 泛型定義法
let arr: Array<number> = [3,4,5]
聯(lián)合類型 |
聯(lián)合類型由|符號實現(xiàn)
let a : number | string = ''qq
// 使用常量作為類型,變量的值只能是它們
let num : 1|'2' = 1
num = '2'
// num的值只能是1或者'2',不能是其他值
交叉類型&
交叉類型需要同時滿足才可以
let obj : {name: string, age: number} & {height:number} = {
name: 'zhangsan',
age: 17,
height: 10
}
name\age\height需要同時都有才可以
any和unknown的區(qū)別
any會繞過類型的檢驗,好似在寫js,但是unknown不會繞過類型檢測,可以給它賦任何類型的值
interface 接口
- 對象接口
interface MyItf {
name: string;
age: number;
height: number;
}
let obj:MyItf = {
name: 'zhangsan',
age:18,
height:170
}
- 數(shù)組接口
interface ArrItf {
// 下標類型:值類型
[idx:number]: number|string
}
let arr:ArrItf = [1,2,3,'4','5']
- 函數(shù)接口
// 匿名函數(shù)
interface FnItf {
// 形參類型:返回值類型
(p:string):void
}
let fn:FnItf = (p:string) => {}
// 對象屬性中的函數(shù)
interface PersonItf {
name:string;
getName:() => string;
}
let person:PersonItf ={
name: '',
getName() {
return ''
}
}
- 接口繼承
接口通過extends來實現(xiàn)繼承
interface NameItf {
name: string
}
interface AgeItf {
age: number
}
interface PersonItf extends NameItf , AgeItf {
height: number
}
// 此時PersonItf 接口有name、age、height三個屬性
let person:PersonItf = {
name: 'zhangsan',
age: 18,
height: 170
}
- 接口同名
接口同名類似于合并了同名的所有接口
interface AItf {
a: number
}
interface AItf {
b: string
}
let a:AItf = {
// 此時的a需要同時寫上a和b屬性
a: 1,
b: 'vvv'
}
- 接口缺省
接口使用?來實現(xiàn)缺省,類似于可選
interface PersonItf {
name?: string,
age: number
}
// 這樣寫name屬性可以不寫
let person:PersonItf = {
age: 18
}
- 只讀 readonly
如果接口中的某個屬性是只讀的,只需要在屬性名前加上readonly即可
interface PersonItf {
readonly name: string
}
let person: PersonItf = {
name: 'Tony'
}
// person的name屬性不支持修改
聯(lián)合交叉類型
聯(lián)合交叉類型:同時使用&和|,在ts中&的優(yōu)先級高于|
類型別名
可以通過關(guān)鍵字type定義類型別名,
type StrOrNum = string | number
let str:StrOrNum = '123'
type ObjType = { a:number&2, b:string}
let obj:ObjType = {
a:2,
b: 'qq'
}
類型別名和interface的區(qū)別
- 都可以用來自定義類型
- 類型別名不支持重復定義,接口支持重復定義
- 類型別名支持聯(lián)合類型和交叉類型
函數(shù)
- 使用接口來定義函數(shù)類型
interface FnItf {
(k:string):number
}
let fn:FnItf = (k:string) => {
return 1
}
- 使用類型別名定義函數(shù)類型
type FnType = (k:string) => void
let fn:FnType = (k:string):void => {}
- 函數(shù)作為對象的屬性
// interface實現(xiàn)
interface FnItf {
(k:string):number
}
interface ObjItf {
fn: FnItf
}
let obj:ObjItf = {
fn: (k:string) => { return 1 }
}
// 類型別名實現(xiàn)
type FnType = (k:string) => void
type ObjType = {
fn: FnType
}
let obj:ObjType = {
fn: () => {}
}
函數(shù)參數(shù)
- 默認參數(shù)
function add(a:number, b: number = 3):number {
return a + b
}
add(1, 2) // 3
add(4) // 7
- 可選參數(shù)
function add(a:number, b?:number) :number{
if(b) {
return a + b
}
return a
}
- 剩余參數(shù)
function add (a:number, b:number, ...arr:number[]) {
}
add(1,2,3,4,5)
Promise
在ts中寫Promise
interface DataItf {
a: number;
b: number;
}
interface ResItf {
code: number;
data: DataItf [],
message: string
}
let p:Promise<ResItf> = new Promise((resolve, reject) => {
resolve({
code: 1,
data: [{a: 1, b:2},{a:3,b:4}],
message: 'success'
})
})
全局聲明文件
ts 中以.d.ts結(jié)尾的文件是全局聲明文件,可以理解成定義全局類型變量的文件,在其他ts文件中使用全局聲明文件中的內(nèi)容時無需引入
枚舉
枚舉不是用來定義類型的,是用來列舉數(shù)據(jù)的
enum Status {
Succ = 200,
ParamsError = 400,
ServerErroe = 500
}
let code : number | string = 200
if (code === Status.Succ) {
console.log('success')
}
泛型
泛型可以理解成類型的形參
// T只是一個標識符,可以自定義,T表示某種類型
function fn<T>(n:T):T{
return n
}
fn<number>(100)
// 類型也可以使用多個
function fn<T,U>(n:T, m:U):T{
return n
}
fn<number,string>(1,'q')
- 類型別名中的泛型
type objType<T,G> = {
name: T,
getName: () => G
}
type strOrNum = string | number
let obj:objType<strOrNum, strOrNum> = {
name: '1',
getName(){
return ''
}
}
- 接口中的泛型
interface PersonItf<T,U> {
name:T;
getName:() => U;
}
let person:PersonItf<string,string> ={
name: '',
getName() {
return ''
}
}
- 泛型默認值
interface PersonItf<T,U=string> {
name:T;
getName:() => U;
}
let person:PersonItf<string> ={
name: '',
getName() {
return ''
}
}
- 泛型約束
泛型可以使用extends來實現(xiàn)約束
interface PersonItf<T extends number ,U=string> {
name:T;
getName:() => U;
}
let person:PersonItf<number> ={
name: 1,
getName() {
return ''
}
}
Class
ts中定義類需要先定義類的屬性,同時定義的類ts會同步定義一個相同名字的接口
class Person{
myName:string = ''
constructor(name:string) {
this.myName = name
}
getName(){
return this.myName
}
}
// ts自動定義了一個同名接口
let person:Person = {
myName: '',
getName(){
return ''
}
}
- 類的繼承extends
class Person{
myName:string = ''
constructor(name:string) {
this.myName = name
}
getName(){
return this.myName
}
}
class Male extends Person {
myAge: number
constructor(name:string, age:number) {
super(name)
this.myAge = age
}
}
類的修飾符
- public 被修飾的屬性和方法在類中和類外都可以訪問
- private 私有的,在類里面可以訪問,子類和類的外部都不能訪問
工具類型 Partial
Partial(部分的):是TS內(nèi)置的工具類型,被Partial修飾的接口相當于添加了缺省符號?
interface PItf {
name: string;
age: number;
}
// 如果不使用Partial 下面的對象就會報錯
let obj:Partial<PItf> = {
name:''
}
工具類型 Required
Required與Partial正好相反,Required是抵消調(diào)缺省,被Required修飾的接口中的缺省符會被抵消,變成必須項
interface PItf {
name: string;
age: number;
height?: number
}
let obj:Partial<PItf> = {
name:''
}
let obj1:Required<PItf> = {
name: '',
age: 12,
height: 12
}