-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
342 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
//对象 | ||
|
||
interface paintOption { | ||
shape: "circle" | "square"; | ||
xPos?: number; | ||
yPos?: number; | ||
} | ||
|
||
function paintShape({ shape, xPos = 0, yPos = 0 }: paintOption) { | ||
console.log(shape, xPos, yPos); | ||
} | ||
|
||
paintShape({ shape: "circle", xPos: 100, yPos: 100 }); | ||
paintShape({ shape: "circle" }); | ||
paintShape({ shape: "square", yPos: 100 }); | ||
|
||
//泛型定义类型 | ||
interface Box<T> { | ||
content: T | ||
} | ||
let myBox: Box<string> = { content: "hello" }; | ||
|
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
//泛型 | ||
|
||
//keyof | ||
//一个泛型参数来约束另一个泛型参数 如下面,我们约束 Key得是T的属性之一 | ||
function getProperty<T, Key extends keyof T>(obj: T, keyName: Key) { | ||
return obj[keyName]; | ||
} | ||
|
||
let user = { | ||
name: "Tom", | ||
age: 12 | ||
} | ||
console.log(getProperty(user, "name")); //Tom | ||
|
||
//泛型引入构造函数 | ||
class User { | ||
name = "Tom"; | ||
age = 12; | ||
constructor() { | ||
} | ||
sayHello() { | ||
console.log("hello", this.name); | ||
} | ||
} | ||
|
||
function create<T>(con: new () => T): T { | ||
return new con(); | ||
} | ||
|
||
create(User).sayHello(); | ||
|
||
|
||
//索引类型 | ||
type Person = { age: number, name: string, alive: boolean } | ||
type KSet = keyof Person; //"age"|"name"|"alive" | ||
type Age = Person["age"]; | ||
type ValueSet = Person[KSet]; //number | string | boolean Person[keyof Person] | ||
|
||
let a: Age = 12; | ||
let b: KSet = "age"; | ||
let c: ValueSet = true; | ||
|
||
|
||
const MyArray = [ | ||
{ name: "Alice", age: 15 }, | ||
{ name: "Bob", age: 23 }, | ||
{ name: "Eve", age: 38 }, | ||
]; | ||
|
||
type Person2 = typeof MyArray[number]; | ||
let d: Person2 = { | ||
name: "Hello", | ||
age: 15 | ||
} | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// 条件类型 | ||
//ts的条件类型就是可以判断一个类型是否继承自另一个类型 但这个三元表达式只能返回类型,也即赋值给type | ||
// SomeType extends OtherType ? TrueType : FalseType; | ||
|
||
class Animal300 { | ||
|
||
} | ||
class Dog extends Animal300 { | ||
|
||
} | ||
|
||
type example = Dog extends Animal300 ? number : string; | ||
|
||
//不行 | ||
// let a:example = "123" | ||
//可以 | ||
let a: example = 123; | ||
|
||
//看一个更复杂的例子 | ||
interface IdLabel { | ||
id: number; | ||
} | ||
interface NameLabel { | ||
name: string; | ||
} | ||
//与泛型一起用 可以看到ts的类型系统很复杂 | ||
type NameOrId<T extends number | string> = T extends number ? IdLabel : NameLabel; | ||
function createLabel<T extends number | string>(idOrName: T): NameOrId<T> { | ||
if (typeof idOrName === 'number') { | ||
return { | ||
id: idOrName | ||
} as NameOrId<T> | ||
} else { | ||
return { | ||
name: idOrName | ||
} as NameOrId<T> | ||
} | ||
} | ||
|
||
let result1: NameLabel = createLabel("hello"); | ||
let result2: IdLabel = createLabel(11); | ||
|
||
//与泛型一起 做类型约束 | ||
//如下代表:如果泛型T包含属性message,则MessageOf代表T["message"]的类型,否则MessageOf代表never | ||
type MessageOf<T> = T extends { message: unknown } ? T["message"] : never; | ||
//如: | ||
interface User300 { | ||
name: string; | ||
length: number; | ||
message: string | ||
} | ||
interface User301 { | ||
name: string; | ||
length: number; | ||
} | ||
//其中就是string | ||
let str: MessageOf<User300> = "hello"; | ||
//下面就不能将string赋值给never | ||
// let neverX: MessageOf<User301> = "11"; | ||
|
||
//再看个例子,如果类型T是数组,则Flatten是数组元素类型,否则Flatten是T本身类型 | ||
type Flatten<T> = T extends any[] ? T[number] : T; | ||
let userArray = [ | ||
{ name: "hello", age: 123 }, | ||
{ name: "hello2", age: 1234 }, | ||
{ name: "hello3", age: 12345 } | ||
] | ||
let user: Flatten<typeof userArray> = { | ||
name: "hello", | ||
age: 123 | ||
} | ||
let ageXX: Flatten<number> = 123; | ||
|
||
|
||
//将T扩展成数组 | ||
type toArray<T> = T extends any ? T[] : never; | ||
type strArrayOrNumberArray = toArray<string | number>; //string[] | number[] | ||
|
||
let strArray: strArrayOrNumberArray = ["1234", "2345", "3456"]; | ||
let numberArray: strArrayOrNumberArray = [1234, 2345, 3456]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
//映射类型 | ||
//在说映射类型前 再聊下索引签名 在ts中核心解决的是如何描述一个数据结构的类型 | ||
//索引签名解决的是 对于一个尚未声明的结构,我们如何规范这个结构,假设我现在有一个user对象,如何规范这个user呢? | ||
|
||
type UserIndex = { | ||
[key: string]: string | ||
} | ||
//如上 我们规定结构UserIndex必须是key是string value也是string类型,比如: | ||
let user320: UserIndex = { | ||
name: "Tom" | ||
} | ||
//上面这个是ok的,但如果我们写成: | ||
// let user321: UserIndex = { | ||
// age: 12 | ||
// } | ||
// 就不行 | ||
//我们可以通过索引类型拿到一个已知对象的value类型: | ||
let user302 = { | ||
name: "hello", | ||
age: 123, | ||
alive: true | ||
} | ||
//此时User302Type就是 string | number | boolean | ||
type User302Type = (typeof user302)["name" | "age" | "alive"]; | ||
//索引类型的核心是通过索引拿到value的类型,还可以通过keyof这样 这种情况与上面的结果一样 keyof就是上面的"name" | "age" | "alive" | ||
type User302Type1 = (typeof user302)[keyof typeof user302]; | ||
|
||
//索引类型+泛型 = 映射类型 | ||
type OptionsFlags<T> = { | ||
[Property in keyof T]: boolean; | ||
} | ||
//我们分析下上例: | ||
//keyof T是拿到类型T的每个属性 property就是上面的每个属性 并将每个属性变为boolean,举个例子: | ||
interface User303 { | ||
name: string, | ||
age: number | ||
} | ||
//上面我们定义了name和age两个属性,分别是string和number,但通过OptionsFlags一转化 | ||
//得到的新属性其实是:{name:boolean,age:boolean} 将上面这些属性的类型都改为了boolean 属性名保留,类型被替换了 | ||
type User303Flag = OptionsFlags<User303>; | ||
let user303FlagObj: User303Flag = { | ||
name: true, | ||
age: false | ||
} | ||
//所以映射修改器就是将原来Type内属性的类型改为其他类型 | ||
//同时映射属性还可以修改可选性?与可变性readOnly 改变的意思是可以添加或者删除 也即添加上可选性/可变性 或者删除可选性 可变性 https://www.typescriptlang.org/docs/handbook/2/mapped-types.html | ||
type OptionsFlags2<T> = { | ||
[property in keyof T]?: T[property]; | ||
} | ||
//可以不写任何属性,因为都是可选 | ||
let user303FlagObj2: OptionsFlags2<User303> = { | ||
} | ||
|
||
//除了可以更改value类型,还可以通过as 更改属性名字: | ||
//Capitalize是ts中的类型操作符,用于在类型层面将字符串类型的首字母大写 如:type small = "hello" type CapitalizedSmall = Capitalize<Small>; // 类型为 'Hello' | ||
//而string&property是明确告诉Capitalize我的property是string类型的 | ||
type ToGetter<T> = { | ||
[property in keyof T as `get${Capitalize<string & property>}`]: () => T[property]; | ||
} | ||
|
||
interface User304 { | ||
name: string, | ||
age: number | ||
} | ||
type UserGetter = ToGetter<User304>; | ||
let userGetterObj: UserGetter = { | ||
getName() { | ||
return "hello"; | ||
}, | ||
getAge() { | ||
return 12; | ||
} | ||
} | ||
|
||
//Exclude操作符可以删除某些属性 | ||
type ExcludeType<T, V> = { | ||
[property in keyof T as Exclude<property, V>]: T[property] | ||
} | ||
|
||
//删除name属性 这个还是挺普遍用的,可以传入两个参数,来删除指定类型的指定属性 | ||
type ExcludeUser304 = ExcludeType<User304, "name">; | ||
let excludeUser304Obj: ExcludeUser304 = { | ||
age: 12, | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
interface User400 { | ||
name: string, | ||
sayIt: () => void; | ||
} | ||
|
||
//函数加了this挺麻烦的,有些类似于go中的方法,函数绑了对象 | ||
//这种时候只能通过对象.函数名()调用 | ||
function sayHello(this: User400) { | ||
console.log(this.name); | ||
} | ||
|
||
let user400: User400 = { | ||
name: "Tom", | ||
sayIt: sayHello | ||
} | ||
user400.sayIt(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
interface User { | ||
login: string; | ||
id: number; | ||
node_id: string; | ||
avatar_url: string; | ||
gravatar_id: string; | ||
url: string; | ||
html_url: string; | ||
followers_url: string; | ||
following_url: string; | ||
gists_url: string; | ||
starred_url: string; | ||
subscriptions_url: string; | ||
organizations_url: string; | ||
repos_url: string; | ||
events_url: string; | ||
received_events_url: string; | ||
type: string; | ||
site_admin: boolean; | ||
name: string; | ||
company: string; | ||
blog: string; | ||
location: string; | ||
email: null; | ||
hireable: null; | ||
bio: string; | ||
twitter_username: null; | ||
public_repos: number; | ||
public_gists: number; | ||
followers: number; | ||
following: number; | ||
created_at: string; | ||
updated_at: string; | ||
} | ||
|
||
|
||
async function test() { | ||
let url = 'https://api.github.com/users/coderzoe'; | ||
let response = await fetch(url) | ||
let user: User = await response.json(); //通过js的强类型 | ||
console.log(user.login); | ||
} | ||
|
||
|
||
async function process() { | ||
let url: string = "https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits?per_page=100"; | ||
const response = await fetch(url); | ||
const reader = response.body!.getReader(); | ||
// console.log('aaa', response.headers.get("Content-Length")); | ||
console.log('aaa', response.headers.get("Transfer-Encoding")); | ||
const totalLength = Number(response.headers.get("Content-Length")); | ||
let received = 0; | ||
while (true) { | ||
const { done, value } = await reader!.read(); | ||
if (done) { | ||
console.log(`总共需要接收${totalLength},现在接收${received}`); | ||
break; | ||
} | ||
received += value.length; | ||
console.log(`总共需要接收${totalLength},现在接收${received}`); | ||
} | ||
} | ||
|
||
|
||
async function abort() { | ||
let controller = new AbortController(); | ||
controller.signal.addEventListener("abort", event => { | ||
console.log("任务停止"); | ||
}); | ||
let url = "https://api.github.com/repos/javascript-tutorial/en.javascript.info/commits?per_page=100"; | ||
let response = await fetch(url, { | ||
signal: controller.signal | ||
}); | ||
setTimeout(() => { | ||
//调用终止操作 | ||
controller.abort(); | ||
}, 100); | ||
|
||
} | ||
test() | ||
process(); | ||
abort(); |