unionとtupleの変換
型パズル
code:ts
interface Person {
name: string;
age: number;
}
ここから["name", "age"]を取り出したい
interfaceからkeyofで"name" | "age"を取ることはできるので、tupleとunionの変換という観点になる
tupleからunionは簡単
["name", "age"][number]でいいっぽい
この逆が難しい
なんかhackeyな方法しかないっぽい
https://github.com/microsoft/TypeScript/issues/13298
https://www.typescriptlang.org/play?ssl=11&ssc=38&pln=5&pc=1#code/C4TwDgpgBAKgrmANhAqgOwJYHs0B4VQQAewEaAJgM5SXABOGaA5gDRQBKhJZVUAhmhABtALpQAvFFEA+CVADeAKACQQgMpRGUFCIBcUAKJEAxojjkI+NmtnFSFamggA3CHSgB+KQDpf7a2L68EiomDi4RqbmlijW0mxCvt7+UGoi0gDcigC+QjpZioykdABmfMbQAApulDgKilCNUCUYdLQAcnwAthD6tAzMWU1QiHwd3b009IxMQ03kWABG+gAifKRzjQAWYwDC65T6ZYiUEFnZiqCQUADWECDUksHI6Nh4dyBYJVDVbTiZQA
https://www.typescriptlang.org/play?ts=4.5.0-dev.20210809#code/FAYwNghgzlAEBCAJAgsgMrA3rADgJwEsA3CAFwFNYCp4ALCCMWAXllLwFdyBuWAX2DBSATxyUAqgDsCAe0kAVGfI44w5ADzyAfC1gAKYLCP7DxswbOXj82OQAeFSQBM4EScNNWvsAPz7SAFyw8gCULDrynt6WQZLkROR4UWZh9o4uVJIAZomw4slefnritg7kzq7uBdG++hxB4mHMOm4eNVax8YnVlqllFfpEQQTZuQBqTS1V7ZZ+Yz3enQlJM0vdKaXpcHoA+kGtk5k5eLAA6j1+ANoAdLdSsgpKKmrqAKJ24BxOGvIANGdaLT-U4AXR6QUuYJC3EEIjEwWelFY9zkimUqg0ACZYAAfWAARlxsAAzESAKxE-EABiJAFoAJyUqk0vHUqmE1lU7GszHEgAsZIAbEzmaLmUSAESMAggcgSomXRVIVBoEFqyUgeh4MAEOVaGEAegNlgAen5WJdMf98f9if8ydaqf8GY6nQTmTb3VaCbyBYLXWLmf8pTrZRL-orLsr0GqQcHNRBtbqJWCgA
https://www.typescriptlang.org/play?ts=4.5.0-dev.20210809#code/FAFwngDgpgBAagQwDYFcoBUUSVAPAeQBoZ0YoAPEKAOwBMBnGAayjAHsAzGfGAXmdaduAPj4wAFMBjSJUmfMnylM0hSp1GCamDnK9MAPwSQALhIBKPqPS79Ss9SgA3KACdb8y2poMYAS2oONxgAVQ89I3EQskofTW1wu0MJFDMQy15RLR0k5QdnN0SlL1iNCSczAKDXeAyshNylIzgi-XyXd0b2ws8Y9V9xAH0zbLr-QOCAdSKjAG0AOkXEVAwsHAJiAFFyAGNUWjx0YknhYWJ8We2QVwQdkFxJ4hZ2LnxhAF13orNZr-MAbmAoEgsAAsmAAIKuADmjH4AG85AgYQBGMz0a4BaGA6TI6EAJgcKAAtgAjNw4mB4gDM6Mx1GxwAAvoDgdAYAAxMTiRbzPH0MzLNCYbB4cFQ2HCMZONh+WiAoA
関数の交差型の返り値をinferすると、交差の後ろの関数の返り値が得られる
https://github.com/microsoft/TypeScript/issues/13298#issuecomment-885980381
@jo32's solution worked for me, but I turn off use of any throughout my projects. Here is @jo32's solution with the conditional types swapped after extending never (instead of extends any)
https://www.typescriptlang.org/play?ts=4.5.0-dev.20210809#code/C4TwDgpgBAqgdgSwPZwCpIJJ2BATgZwgGNhk4AeGAPigF4oAKAKCliggA8c4ATfKOBABueKAH4Bw0QC5GAQ1wBzWTACUdGoJG4m6ztz7ylshHABmojOto0hSBDxbioGJ7K14A3EyahIsRBR0VABXMAAbCHJUGnp4MnQsHAJiUhRyJ1R2Lghefg9cZwKoWQZgWVRrGlQmGn1cwwYAfXcpXCqoUwtCgHUnCQBtADoR+KCkUIiogFEOInCQnijUABooHqoqNZ6AXTcoAZ3vJlNkszkiaAAFPHwUKABvJ1YzBAJgADk5AFsIWXxgLhTIpvKxWOE5ACvr9-oDgaCwTwkAAjWQAETkOARrAAFpCAMKY-Cyc7hQjeAC+vnA0AA1hAQPw4oE0BMwpFyPSQEgzFAbgQUFRvEA
code:ts
type UnionToIntersection<U> = (
U extends never ? never : (arg: U) => never
) extends (arg: infer I) => void
? I
: never;
type UnionToTuple<T> = UnionToIntersection<
T extends never ? never : (t: T) => T
extends (_: never) => infer W
? ...UnionToTuple<Exclude<T, W>>, W
: [];
interface Person {
firstName: string;
lastName: string;
dob: Date;
hasCats: false;
}
type keys = UnionToTuple<keyof Person>;
これがいい感じに見える
実用していいのかは分からない
code:ts
type UnionToIntersection<U> =
(
U extends never ? never : (arg: U) => never
) extends (arg: infer I) => void
? I
: never;
type Hoge5 = UnionToIntersection<string | string> //=> string
type Hoge6 = UnionToIntersection<string | number> //=> never
これもよくわからん
とくに最初のU extends never
これただたんにUのnever判定をしてるだけだとおもったら、違う
ここを削ると挙動が変わった
削ると、Uがそのまま返ってくる
union型をextendsしたときの関数型の挙動を調べる
U extends never ? never : (arg: U) => never
ここはわかった
named tupleとか来てるんだしtupleof みたいな演算子も欲しい
https://stackoverflow.com/questions/53503813/get-dictionary-object-keys-as-tuple-in-typescript
型はexactじゃない
keyの順序の問題