Skip to content

Commit

Permalink
ts
Browse files Browse the repository at this point in the history
  • Loading branch information
coderZoe committed Apr 24, 2024
1 parent 509b4f1 commit 59f5d3c
Show file tree
Hide file tree
Showing 7 changed files with 342 additions and 0 deletions.
22 changes: 22 additions & 0 deletions chapter2/2_4_2.ts
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.
57 changes: 57 additions & 0 deletions chapter2/2_5_2.ts
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
}



80 changes: 80 additions & 0 deletions chapter3/3_1.ts
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];
85 changes: 85 additions & 0 deletions chapter3/3_2.ts
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,
}

16 changes: 16 additions & 0 deletions chapter4/4_1.ts
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();
82 changes: 82 additions & 0 deletions test/test.ts
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();

0 comments on commit 59f5d3c

Please sign in to comment.