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';
}