Comments (10)
type Permutation<T, K = T> = [T] extends [never] ? [] : K extends K ? [K, ...Permutation<Exclude<T, K>>] : never
from awesome-typescript.
type Permutation<T, K = T> = [T] extends [never] ? [] : K extends K ? [K, ...Permutation<Exclude<T, K>>] : never
初看有些看不懂, 因此详细解释一下这位老哥的解法
// 1. 通过extends语法来对T类型中的或值的每一个值进行遍历
// 如果不理解的可以参考下面的例子:
// type TTT = ['a' | 'b'] extends ['a'] | ['b'] ? true : false // true
// 2. 遍历之后再对后续递归需要使用的K进行遍历(主要是起到排除当前T中的key的效果)
// 同时我们也知道, n个不重复值全排列的值为n的阶乘
// 也就是说我们需要在遍历的时候一直排除当前值, 遍历剩余值即可
// K extends K则是对当前递归场景下的所有key的遍历
// 然后最后, 递归处理剩余的参数即可, 期间使用了扩展运算符来对多维数组进行摊平
// 例如: 对于 'a' | 'b' | 'c' 来说, 会这样产生值
// ['a', ...['b', ...['c']]], ['a', ...['c', ...['b']]] ...
// 完成解构之后, 便成为了期望的 ['a', 'b', 'c'], ['a', 'c', 'b'] ...
type Permutation<T, K = T> = [T] extends [never] ? [] : K extends K ? [K, ...Permutation<Exclude<T, K>>] : never
from awesome-typescript.
// 实现一个 Permutation 工具类型,当输入一个联合类型时,返回一个包含该联合类型的全排列类型数组。具体的使用示例如下所示:
type Om<T, I> = T extends I ? never : T;
type Test<T extends any[], F, G = F> = T extends any[]
? F | 1 extends 1
? T
: F extends any
? Test<[...T, F], Om<G, F>>
: T
: T;
type Permutation<T> = Test<[], T>;
// ["a", "b"] | ["b", "a"]
type P0 = Permutation<"a" | "b">; // ['a', 'b'] | ['b' | 'a']
// type P1 = ["a", "b", "c"] | ["a", "c", "b"] | ["b", "a", "c"]
// | ["b", "c", "a"] | ["c", "a", "b"] | ["c", "b", "a"]
type P1 = Permutation<"a" | "b" | "c">
from awesome-typescript.
type Permutation<T, K = T> =
[T] extends [never]
? []
: T extends K
? [
T,
...Permutation<Exclude<K, T>>
]
: never
// 你的实现代码
// ["a", "b"] | ["b", "a"]
type P0 = Permutation<'a' | 'b'> // ['a', 'b'] | ['b' , 'a']
// type P1 = ["a", "b", "c"] | ["a", "c", "b"] | ["b", "a", "c"]
// | ["b", "c", "a"] | ["c", "a", "b"] | ["c", "b", "a"]
type P1 = Permutation<'a' | 'b' | 'c'>
from awesome-typescript.
//* 实现一个 Permutation 工具类型,当输入一个联合类型时,返回一个包含该联合类型的全排列类型数组。
type IsNever<T> = [T] extends [never] ? true : false;
type Permutation<T extends string | number | symbol> = {
[index in T]: IsNever<Exclude<T,index>> extends true ? [index] : [index, ...Permutation<Exclude<T ,index>>]
}[T];
type PP = Permutation<'a'>
// ["a", "b"] | ["b", "a"]
type P0 = Permutation<'a' | 'b'> // ['a', 'b'] | ['b' | 'a']
// type P1 = ["a", "b", "c"] | ["a", "c", "b"] | ["b", "a", "c"]
// | ["b", "c", "a"] | ["c", "a", "b"] | ["c", "b", "a"]
type P1 = Permutation<'a' | 'b' | 'c'>
from awesome-typescript.
type Permutation<T, K=T> = T extends K
?[T,...Permutation<K,Exclude<K,T>>]
:[]
这个实现看着也可以,不知有没有什么弊端
from awesome-typescript.
type Permutation<T, K = T>
= [T] extends [never]
? []
: K extends any
? [K, ...Permutation<Exclude<T, K>>]
: never
// ["a", "b"] | ["b", "a"]
type P0 = Permutation<"a" | "b">;
// type P1 = ["a", "b", "c"] | ["a", "c", "b"] | ["b", "a", "c"]
// | ["b", "c", "a"] | ["c", "a", "b"] | ["c", "b", "a"]
type P1 = Permutation<"a" | "b" | "c">;
from awesome-typescript.
type Permutation<T, K = T>
= T extends any
? Exclude<K, T> extends never
? [T]
: [T, ...Permutation<Exclude<K, T>>]
: never
from awesome-typescript.
type Permutation<T, K = T>
= T extends any
? Exclude<K, T> extends never
? [T]
: [T, ...Permutation<Exclude<K, T>>]
: never
from awesome-typescript.
type Permutation<T, K = T> = [T] extends [never] ? [] : K extends K ? [K, ...Permutation<Exclude<T, K>>] : never初看有些看不懂, 因此详细解释一下这位老哥的解法
// 1. 通过extends语法来对T类型中的或值的每一个值进行遍历 // 如果不理解的可以参考下面的例子: // type TTT = ['a' | 'b'] extends ['a'] | ['b'] ? true : false // true // 2. 遍历之后再对后续递归需要使用的K进行遍历(主要是起到排除当前T中的key的效果) // 同时我们也知道, n个不重复值全排列的值为n的阶乘 // 也就是说我们需要在遍历的时候一直排除当前值, 遍历剩余值即可 // K extends K则是对当前递归场景下的所有key的遍历 // 然后最后, 递归处理剩余的参数即可, 期间使用了扩展运算符来对多维数组进行摊平 // 例如: 对于 'a' | 'b' | 'c' 来说, 会这样产生值 // ['a', ...['b', ...['c']]], ['a', ...['c', ...['b']]] ... // 完成解构之后, 便成为了期望的 ['a', 'b', 'c'], ['a', 'c', 'b'] ... type Permutation<T, K = T> = [T] extends [never] ? [] : K extends K ? [K, ...Permutation<Exclude<T, K>>] : never
这位老哥已经解析的很好了,补充下最前面
[T] extends [never]
是干嘛的?
因为递归调用,参数T 就是上一轮的 Exclude<T, K>
, 那么就可能会出现 Exclude<'a', 'a'>
即 never
的情况,[T] extends [never]
就是判断T是否为never, 是的话返回一个空数组即可。
from awesome-typescript.
Related Issues (20)
- typescript练习第二题
- 报错的原因是返回值类型不匹配,返回值的类型是User,但T比User的范围更大
- ...
- #### 7.1 EmptyObject
- 「重学TS 2.0 」TS 练习题第四十一题 HOT 9
- 「重学TS 2.0 」TS 练习题第四十二题 HOT 12
- 「重学TS 2.0 」TS 练习题第四十四题 HOT 4
- 「重学TS 2.0 」TS 练习题第四十五题 HOT 4
- 「重学TS 2.0 」TS 练习题第四十六题 HOT 5
- 「重学TS 2.0 」TS 练习题第四十七题 HOT 7
- 「重学TS 2.0 」TS 练习题第四十八题 HOT 4
- readme里的电子书下载地址403了 HOT 2
- 疑惑返回类型加Partial为什么不行 HOT 1
- 第一题
- 收藏学习!!!
- 抱歉,点击错了
- 「重学TS 2.0 」TS 练习题第四十九题 HOT 4
- > ```ts
- 练习第一题 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from awesome-typescript.