typescript 技巧學習

typescript 差缺補漏

資料

交叉點類型

交集類型是將多個類型組合爲一種的方法,就是多個類型的合併

type LeftType = {
  id: number
  left: string
}

type RightType = {
  id: number
  right: string
}

type IntersectionType = LeftType & RightType

function showType(args: IntersectionType) {
  console.log(args)
}

showType({ id: 1, left: "test", right: "test" })
// Output: {id: 1, left: "test", right: "test"}

聯合類型用的比較多

let a:number|string;

通用類型感覺這個很厲害

構造泛型類型,用方括號T作爲參數傳遞

interface GenericType<T> {
  id: number,
  name: T
}

function showType(args: GenericType<string>) {
  console.log(args);
}

function showTypeTwo(args: GenericType<number>) {
  console.log(args);
}

showType({id: 10, name: 'xxx'});
showTypeTwo({id: 10, name: 20});

我以前以爲只能用T,今天看了大佬的代碼,發現原來T只是一個符號,學習到了

interface GenericType<T,D>{
  id:T,
  name:D
}

function showType(args: GenericType<number, string>) {
  console.log(args);
}
showType({id:20, name: 'ss'});

function showTypeTwo(args: GenericType<number, Array<string>>) {
  
}
showTypeTwo({id:10, name: ['a', 'b', 'c']})

可選

Partial<T>

interface PartialType {
id: number
firstName: string
lastName: string
}

function showType(args: Partial<PartialType>) {
console.log(args)
}

showType({ id: 1 })
// Output: {id: 1}

showType({ firstName: "John", lastName: "Doe" })
// Output: {firstName: "John", lastName: "Doe"}

必傳

Required<T>

提供的T需要傳所有類型的屬性

interface RequiredType {
id: number
firstName?: string
lastName?: string
}

function showType(args: Required<RequiredType>) {
console.log(args)
}

showType({ id: 1, firstName: "John", lastName: "Doe" })
// Output: { id: 1, firstName: "John", lastName: "Doe" }

showType({ id: 1 })
//報錯啦

只讀

Readonly<T>

T無法使用新值重新分配

interface ReadonlyType {
id: number
name: string
}

function showType(args: Readonly<ReadonlyType>) {
args.id = 4
console.log(args)
}
showType({ id: 1, name: "Doe" })
// error 報錯了,他的值都不能被修改
不過下面這樣寫也不錯
interface ReadonlyType {
readonly id: number
name: string
}

忽略

Omit<T,k>

將K從屬性T 刪除

簡單的說就是我輸入類型不能帶入k,不然會報錯

interface PickType {
id: number
firstName: string
lastName: string
}

function showType(args: Omit<PickType, "firstName" | "lastName">) {
console.log(args)
}
showType({id: 12})
// 正常
// 帶有firstName 或者 lastName就會報錯

挑選

Pick<T,K>

T中要有屬性k

interface PickType {
id: number
firstName: string
lastName: string,
name: string
}

function showType(args: Pick<PickType, 'firstName' | 'lastName'>) {
console.log(args);
}

showType({lastName: 'xx', firstName: 'xx'});
showType({lastName: 'xx', firstName: 'xx', id: 12});
// 報錯
showType({lastName: 'xx', firstName: 'xx', name:'xx'});
// 報錯

仔細的理解了下,就是類型中只能包含firstName 和 lastName,所以可以理解成挑選

k就是你要選擇的屬性,你可以用|進行分隔選擇多個字段

記錄

Record<K,T>

將一個類型的屬性K映射到另一個類型的屬性

interface EmployeeType {
id: number
fullname: string
role: string
}

let employees: Record<number, EmployeeType> = {
0: { id: 1, fullname: "John Doe", role: "Designer" },
1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
2: { id: 3, fullname: "Sara Duckson", role: "Developer" },
}
// 0: { id: 1, fullname: "John Doe", role: "Designer" },
// 1: { id: 2, fullname: "Ibrahima Fall", role: "Developer" },
// 2: { id: 3, fullname: "Sara Duckson", role: "Developer" }

映射類型

把每個屬性轉換爲新類型

type StringMap<T> = {
[P in keyof T]: string
}

function showType(arg: StringMap<{ id: number; name: string }>) {
console.log(arg)
}
showType({name:'xx',id:'ss'})
//就是把已經的屬性都轉成string
showType({ id: 1, name: "Test" })
// 會報錯

類型防護

typeof

function showType(x: number | string) {
  if (typeof x === "number") {
    return `The result is ${x + x}`
  }
  throw new Error(`This operation can't be done on a ${typeof x}`)
}

showType("I'm not a number")
// Error: This operation can't be done on a string

showType(7)
// Output: The result is 14

instanceof

class Foo {
  bar() {
    return "Hello World"
  }
}

class Bar {
  baz = "123"
}

function showType(arg: Foo | Bar) {
  if (arg instanceof Foo) {
    console.log(arg.bar())
    return arg.bar()
  }

  throw new Error("The type is not supported")
}

showType(new Foo())
// Output: Hello World

showType(new Bar())
// Error: The type is not supported

in

忽略的點看來我之前的寫法沒這種好

interface Bookes {
  id: number,
  name: string
}

books: Bookes[] = [
    {id: 1, name: 'Angular'},
    {id: 2, name: 'Typescript'},
    {id: 3, name: 'Javascript'},
    {id: 4, name: 'HTML'}
  ];

發現一個奇怪的!

!只是用來判斷null和undefined;

as則可用於變更(縮小或者放大都可以)類型檢測範圍

as和!用於屬性的讀取,都可以縮小類型檢查範圍,都做判空用途時是等價的。只是!具體用於告知編譯器此值不可能爲空值(null和undefined),而as不限於此

?可用於屬性的定義和讀取,讀取時告訴編譯器此值可能爲空值(null和undefined),需要做判斷。

interface InterArray {
  children?: InterArrayOne
}

interface InterArrayOne {
  name: string,
  age: number
}
export class OneComponent implements OnInit {
  public a: (InterArrayOne & InterArray) [] = [{
    name: 'xx',
    age: 12,
    children: {
      name: 'aaa',
      age: 12
    }
  },
    {
      name: 'aa',
      age: 13,
    },

  ];
  add(): void {
    for (let i = 0; i < this.a.length; i++) {
      console.log(this.a[i]!.children?.name);
    }
  }
  ngOnInit(): void {
    this.add();
  }
}

類型謂詞

function isString(x: any): x is string {
  return typeof x === 'string';
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章