Skip to content
Open

m #7

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"cSpell.words": [
"unknow"
]
}
8 changes: 7 additions & 1 deletion typechallenges/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# TypeChallenges

## 使用集合的思想理解 ts

## keywords

[x] interface
Expand All @@ -11,7 +13,9 @@
[x] object
[ ] unknown

[ ] never
[x] never:相当于空集,never 是任何类型的子集
[x] unknow: 相当于全集,是所有类型的父集
[x] any: 相当于 unknow 和 never 的结合体,any是所有类型的子集,同时也是所有类型的父集。
[ ] extends
[ ] infer
[ ] namespace/module
Expand Down Expand Up @@ -118,3 +122,5 @@ type A = P<never> // 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)
25 changes: 12 additions & 13 deletions typechallenges/easy/00004-easy-pick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,32 +31,31 @@

/* _____________ Your Code Here _____________ */

type MyPick<T, K extends keyof T> = { [P in K]: T[P]}

type MyPick<T, K extends keyof T> = { [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<Equal<Expected1, MyPick<Todo, 'title'>>>,
Expect<Equal<Expected2, MyPick<Todo, 'title' | 'completed'>>>,
Expect<Equal<Expected1, MyPick<Todo, "title">>>,
Expect<Equal<Expected2, MyPick<Todo, "title" | "completed">>>,
// @ts-expect-error
MyPick<Todo, 'title' | 'completed' | 'invalid'>,
]
MyPick<Todo, "title" | "completed" | "invalid">
];

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 _____________ */
Expand Down
55 changes: 55 additions & 0 deletions typechallenges/easy/00007-easy-readonly.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
7 - Readonly
-------
by Anthony Fu (@antfu) #easy #built-in #readonly #object-keys

### Question

Implement the built-in `Readonly<T>` 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<Todo> = {
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<T> = { readonly [P in keyof T]: T[P] };

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from "@type-challenges/utils";

type cases = [Expect<Equal<MyReadonly<Todo1>, Readonly<Todo1>>>];

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
*/
54 changes: 54 additions & 0 deletions typechallenges/easy/00011-easy-tuple-to-object.ts
Original file line number Diff line number Diff line change
@@ -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<typeof tuple> // 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<T extends readonly any[]> = {[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<typeof tupleNumber>

type cases = [
Expect<Equal<TupleToObject<typeof tuple>, { 'tesla': 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y' }>>,
Expect<Equal<TupleToObject<typeof tupleNumber>, { 1: 1, 2: 2, 3: 3, 4: 4 }>>,
Expect<Equal<TupleToObject<typeof tupleSymbol>, { [sym1]: typeof sym1, [sym2]: typeof sym2 }>>,
Expect<Equal<TupleToObject<typeof tupleMix>, { 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
*/
53 changes: 53 additions & 0 deletions typechallenges/easy/00014-easy-first-of-array.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
14 - First of Array
-------
by Anthony Fu (@antfu) #easy #array

### Question

Implement a generic `First<T>` 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<arr1> // expected to be 'a'
type head2 = First<arr2> // expected to be 3
```

> View on GitHub: https://tsch.js.org/14
*/

/* _____________ Your Code Here _____________ */

// type First<T extends any[]> = T extends [] ? never : T[0];
// type First<T extends any[]> = T["length"] extends 0 ? never : T[0];
type First<T extends any[]> = T extends { length: 0 } ? never : T[0];

type f = First<[]>;

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from "@type-challenges/utils";

type cases = [
Expect<Equal<First<[3, 2, 1]>, 3>>,
Expect<Equal<First<[() => 123, { a: string }]>, () => 123>>,
Expect<Equal<First<[]>, never>>,
Expect<Equal<First<[undefined]>, 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
*/
49 changes: 49 additions & 0 deletions typechallenges/easy/00018-easy-length-of-tuple.ts
Original file line number Diff line number Diff line change
@@ -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<tesla> // expected 4
type spaceXLength = Length<spaceX> // expected 5
```

> View on GitHub: https://tsch.js.org/18
*/

/* _____________ Your Code Here _____________ */

type Length<T> = 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<Equal<Length<typeof tesla>, 4>>,
Expect<Equal<Length<typeof spaceX>, 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
*/