diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..433d216 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "cSpell.words": [ + "unknow" + ] +} \ No newline at end of file diff --git a/typechallenges/README.md b/typechallenges/README.md index 683afb9..5c600c8 100644 --- a/typechallenges/README.md +++ b/typechallenges/README.md @@ -1,5 +1,7 @@ # TypeChallenges +## 使用集合的思想理解 ts + ## keywords [x] interface @@ -11,7 +13,9 @@ [x] object [ ] unknown -[ ] never +[x] never:相当于空集,never 是任何类型的子集 +[x] unknow: 相当于全集,是所有类型的父集 +[x] any: 相当于 unknow 和 never 的结合体,any是所有类型的子集,同时也是所有类型的父集。 [ ] extends [ ] infer [ ] namespace/module @@ -118,3 +122,5 @@ type A = P // string - [TypeScript 类型挑战](https://github.com/type-challenges/type-challenges) - [深入理解 TypeScript](https://jkchao.github.io/typescript-book-chinese/#why) +- [TS类型体操(一) 基础知识](https://juejin.cn/post/7228833037743915067) +- [TypeScript 类型体操指北](https://zhuanlan.zhihu.com/p/452657140) diff --git a/typechallenges/easy/00004-easy-pick.ts b/typechallenges/easy/00004-easy-pick.ts index 34a9810..f4fcd30 100644 --- a/typechallenges/easy/00004-easy-pick.ts +++ b/typechallenges/easy/00004-easy-pick.ts @@ -31,32 +31,31 @@ /* _____________ Your Code Here _____________ */ -type MyPick = { [P in K]: T[P]} - +type MyPick = { [P in K]: T[P] }; /* _____________ Test Cases _____________ */ -import type { Equal, Expect } from '@type-challenges/utils' +import type { Equal, Expect } from "@type-challenges/utils"; type cases = [ - Expect>>, - Expect>>, + Expect>>, + Expect>>, // @ts-expect-error - MyPick, -] + MyPick +]; interface Todo { - title: string - description: string - completed: boolean + title: string; + description: string; + completed: boolean; } interface Expected1 { - title: string + title: string; } interface Expected2 { - title: string - completed: boolean + title: string; + completed: boolean; } /* _____________ Further Steps _____________ */ diff --git a/typechallenges/easy/00007-easy-readonly.ts b/typechallenges/easy/00007-easy-readonly.ts new file mode 100644 index 0000000..46831b5 --- /dev/null +++ b/typechallenges/easy/00007-easy-readonly.ts @@ -0,0 +1,55 @@ +/* + 7 - Readonly + ------- + by Anthony Fu (@antfu) #easy #built-in #readonly #object-keys + + ### Question + + Implement the built-in `Readonly` generic without using it. + + Constructs a type with all properties of T set to readonly, meaning the properties of the constructed type cannot be reassigned. + + For example: + + ```ts + interface Todo { + title: string + description: string + } + + const todo: MyReadonly = { + title: "Hey", + description: "foobar" + } + + todo.title = "Hello" // Error: cannot reassign a readonly property + todo.description = "barFoo" // Error: cannot reassign a readonly property + ``` + + > View on GitHub: https://tsch.js.org/7 +*/ + +/* _____________ Your Code Here _____________ */ + +type MyReadonly = { readonly [P in keyof T]: T[P] }; + +/* _____________ Test Cases _____________ */ +import type { Equal, Expect } from "@type-challenges/utils"; + +type cases = [Expect, Readonly>>]; + +interface Todo1 { + title: string; + description: string; + completed: boolean; + meta: { + author: string; + }; +} + +/* _____________ Further Steps _____________ */ +/* + > Share your solutions: https://tsch.js.org/7/answer + > View solutions: https://tsch.js.org/7/solutions + > More Challenges: https://tsch.js.org +*/ diff --git a/typechallenges/easy/00011-easy-tuple-to-object.ts b/typechallenges/easy/00011-easy-tuple-to-object.ts new file mode 100644 index 0000000..abf9809 --- /dev/null +++ b/typechallenges/easy/00011-easy-tuple-to-object.ts @@ -0,0 +1,54 @@ +/* + 11 - Tuple to Object + ------- + by sinoon (@sinoon) #easy #object-keys + + ### Question + + Given an array, transform it into an object type and the key/value must be in the provided array. + + For example: + + ```ts + const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const + + type result = TupleToObject // expected { 'tesla': 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'} + ``` + + > View on GitHub: https://tsch.js.org/11 +*/ + +/* _____________ Your Code Here _____________ */ + +type TupleToObject = {[P in T[number]] : P} + + + +/* _____________ Test Cases _____________ */ +import type { Equal, Expect } from '@type-challenges/utils' + +const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const +const tupleNumber = [1, 2, 3, 4] as const +const sym1 = Symbol(1) +const sym2 = Symbol(2) +const tupleSymbol = [sym1, sym2] as const +const tupleMix = [1, '2', 3, '4', sym1] as const + +type t = TupleToObject + +type cases = [ + Expect, { 'tesla': 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y' }>>, + Expect, { 1: 1, 2: 2, 3: 3, 4: 4 }>>, + Expect, { [sym1]: typeof sym1, [sym2]: typeof sym2 }>>, + Expect, { 1: 1, '2': '2', 3: 3, '4': '4', [sym1]: typeof sym1 }>>, +] + +// @ts-expect-error +type error = TupleToObject<[[1, 2], {}]> + +/* _____________ Further Steps _____________ */ +/* + > Share your solutions: https://tsch.js.org/11/answer + > View solutions: https://tsch.js.org/11/solutions + > More Challenges: https://tsch.js.org +*/ diff --git a/typechallenges/easy/00014-easy-first-of-array.ts b/typechallenges/easy/00014-easy-first-of-array.ts new file mode 100644 index 0000000..5738516 --- /dev/null +++ b/typechallenges/easy/00014-easy-first-of-array.ts @@ -0,0 +1,53 @@ +/* + 14 - First of Array + ------- + by Anthony Fu (@antfu) #easy #array + + ### Question + + Implement a generic `First` that takes an Array `T` and returns its first element's type. + + For example: + + ```ts + type arr1 = ['a', 'b', 'c'] + type arr2 = [3, 2, 1] + + type head1 = First // expected to be 'a' + type head2 = First // expected to be 3 + ``` + + > View on GitHub: https://tsch.js.org/14 +*/ + +/* _____________ Your Code Here _____________ */ + +// type First = T extends [] ? never : T[0]; +// type First = T["length"] extends 0 ? never : T[0]; +type First = T extends { length: 0 } ? never : T[0]; + +type f = First<[]>; + +/* _____________ Test Cases _____________ */ +import type { Equal, Expect } from "@type-challenges/utils"; + +type cases = [ + Expect, 3>>, + Expect 123, { a: string }]>, () => 123>>, + Expect, never>>, + Expect, undefined>> +]; + +type errors = [ + // @ts-expect-error + First<"notArray">, + // @ts-expect-error + First<{ 0: "arrayLike" }> +]; + +/* _____________ Further Steps _____________ */ +/* + > Share your solutions: https://tsch.js.org/14/answer + > View solutions: https://tsch.js.org/14/solutions + > More Challenges: https://tsch.js.org +*/ diff --git a/typechallenges/easy/00018-easy-length-of-tuple.ts b/typechallenges/easy/00018-easy-length-of-tuple.ts new file mode 100644 index 0000000..9020d5f --- /dev/null +++ b/typechallenges/easy/00018-easy-length-of-tuple.ts @@ -0,0 +1,49 @@ +/* + 18 - Length of Tuple + ------- + by sinoon (@sinoon) #easy #tuple + + ### Question + + For given a tuple, you need create a generic `Length`, pick the length of the tuple + + For example: + + ```ts + type tesla = ['tesla', 'model 3', 'model X', 'model Y'] + type spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT'] + + type teslaLength = Length // expected 4 + type spaceXLength = Length // expected 5 + ``` + + > View on GitHub: https://tsch.js.org/18 +*/ + +/* _____________ Your Code Here _____________ */ + +type Length = T extends {length: number} ? never : T["length"]; + +type z = Length<5> + +/* _____________ Test Cases _____________ */ +import type { Equal, Expect } from '@type-challenges/utils' + +const tesla = ['tesla', 'model 3', 'model X', 'model Y'] as const +const spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT'] as const + +type cases = [ + Expect, 4>>, + Expect, 5>>, + // @ts-expect-error + Length<5>, + // @ts-expect-error + Length<'hello world'>, +] + +/* _____________ Further Steps _____________ */ +/* + > Share your solutions: https://tsch.js.org/18/answer + > View solutions: https://tsch.js.org/18/solutions + > More Challenges: https://tsch.js.org +*/