简体   繁体   中英

How to express idempotent (self flatten) types in TypeScript?

There are types with self flattening nature that is called Idempotence:

在此处输入图片说明

https://en.wikipedia.org/wiki/Idempotence

Idempotence is the property of certain operations in mathematics and computer science whereby they can be applied multiple times without changing the result beyond the initial application.

In JavaScript/TypeScript, we have Object/Number object for instance of idempotence.

A real world use-case is to write your own Promises with proper type in TypeScript. You can never have Promise<Promise<T>> only ever Promise<T> since promises auto-flatten. The same can happen with monads, for example.

 console.log( Number(5) === Number(Number(5)) ); // true

In a concise way, it's often expressed like

TTX = TX

I somehow managed to write in function

const toObject = <A, X>(x: A): A extends T<X> ? A : //...
        ((X:object)=> {/* ... */})(Object(x)) ;

A extends T<X> ? A : //... A extends T<X> ? A : //... works in the context of inside of some functions, but I don't know how to write the type itself alone, and even with function structure, it's very complicated, and I feel something is very wrong.

What I want to know and write is a definition of the idempotent type in TypeScript

type T<X> = ???
//where
T<T<X>> === T<X>

You could write an idempotent wrapper around some inner type:

// just for reference, more practically this could be Promise<T>
type InnerType<T> = [T];
type IdempotentWrapper<X> = X extends InnerType<unknown> ? X : InnerType<X>;

type Foo = IdempotentWrapper<number>; // equivalent to InnerType<number>
type Bar = IdempotentWrapper<IdempotentWrapper<number>>; // equivalent to InnerType<number> as well

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM