aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay Nair <phenax5@gmail.com>2023-01-13 20:32:20 +0530
committerAkshay Nair <phenax5@gmail.com>2023-01-13 20:33:01 +0530
commit518a6a9ee31f0b03f08cb77bc613b4d708bb640b (patch)
tree7f17ce66f337dee573192ce06a24385415048ae2
parent42f8c401dc9519bc8b2d386ce9eda072144a46d0 (diff)
downloadts-types-lang-518a6a9ee31f0b03f08cb77bc613b4d708bb640b.tar.gz
ts-types-lang-518a6a9ee31f0b03f08cb77bc613b4d708bb640b.zip
chore: prettier
-rw-r--r--examples/file.ts8
-rw-r--r--examples/guess-number.ts3
-rw-r--r--examples/hello-world.ts17
-rw-r--r--examples/test-runner.ts42
-rw-r--r--src/context.ts8
-rw-r--r--src/eval-env/builtins.ts236
-rw-r--r--src/eval-env/test.ts2
-rw-r--r--src/eval.ts20
-rw-r--r--src/index.ts7
-rw-r--r--src/types.ts12
-rw-r--r--src/util.ts4
-rw-r--r--stdlib/effect.ts1
-rw-r--r--stdlib/exception.ts2
-rw-r--r--stdlib/nat.ts19
-rw-r--r--stdlib/stdio.ts7
-rw-r--r--stdlib/sys.ts7
-rw-r--r--stdlib/test.ts7
-rw-r--r--stdlib/util.ts8
18 files changed, 206 insertions, 204 deletions
diff --git a/examples/file.ts b/examples/file.ts
index fd5728b..2cc2b7a 100644
--- a/examples/file.ts
+++ b/examples/file.ts
@@ -13,11 +13,5 @@ interface ConstK<Val> extends Kind1<unknown, Val> {
export type main = [
Bind<ReadFile<'./default.nix'>, PrintK>,
- Bind<
- Try<
- ReadFile<'./unicorn'>,
- ConstK<"hello world">
- >,
- PrintK
- >,
+ Bind<Try<ReadFile<'./unicorn'>, ConstK<'hello world'>>, PrintK>
]
diff --git a/examples/guess-number.ts b/examples/guess-number.ts
index 45d60e6..6f5a31b 100644
--- a/examples/guess-number.ts
+++ b/examples/guess-number.ts
@@ -9,7 +9,8 @@ export type main = [
type Len<Ls extends any[]> = Ls['length'] extends number ? Ls['length'] : 0
-interface AskForGuess<N extends number, Attempts extends 0[]> extends Kind1<string> {
+interface AskForGuess<N extends number, Attempts extends 0[]>
+ extends Kind1<string> {
return: `${this['input']}` extends `${N}`
? PutStringLn<'Yay! You got it right!'>
: Do<
diff --git a/examples/hello-world.ts b/examples/hello-world.ts
index fcdb8e9..9d2bc18 100644
--- a/examples/hello-world.ts
+++ b/examples/hello-world.ts
@@ -1,20 +1,13 @@
-import { Bind, Do, Kind1 } from "../stdlib/effect";
-import { CreateRef, GetRef, Ref, SetRef } from "../stdlib/ref";
-import { Print } from "../stdlib/stdio";
+import { Bind, Do, Kind1 } from '../stdlib/effect'
+import { CreateRef, GetRef, Ref, SetRef } from '../stdlib/ref'
+import { Print } from '../stdlib/stdio'
interface PrintK extends Kind1 {
return: Print<this['input']>
}
interface Func extends Kind1<Ref> {
- return: Do<[
- SetRef<this['input'], 69>,
- Bind<GetRef<this['input']>, PrintK>,
- ]>
+ return: Do<[SetRef<this['input'], 69>, Bind<GetRef<this['input']>, PrintK>]>
}
-export type main = [
- Bind<CreateRef<200>, Func>,
- Print<1>,
-]
-
+export type main = [Bind<CreateRef<200>, Func>, Print<1>]
diff --git a/examples/test-runner.ts b/examples/test-runner.ts
index 081dede..7dc1966 100644
--- a/examples/test-runner.ts
+++ b/examples/test-runner.ts
@@ -4,37 +4,37 @@ import { SetEvalEnvironment } from '../stdlib/sys'
import { Test, Assert } from '../stdlib/test'
import { Equals, Not } from '../stdlib/util'
-type testSomeStuff = Do<[
- PutStringLn<"Some Stuff">,
+type testSomeStuff = Do<
+ [
+ PutStringLn<'Some Stuff'>,
- Test<"should do some stuff", [
- Assert<Equals<1, 1>>,
- Assert<Not<Equals<2, 1>>>,
- ]>,
+ Test<
+ 'should do some stuff',
+ [Assert<Equals<1, 1>>, Assert<Not<Equals<2, 1>>>]
+ >,
- Test<"bing bong, bing bing bong", [
- Assert<Equals<1, 1>>,
- ]>,
-]>
+ Test<'bing bong, bing bing bong', [Assert<Equals<1, 1>>]>
+ ]
+>
-type testSomeMoreStuff = Do<[
- PutStringLn<"Other stuff?">,
+type testSomeMoreStuff = Do<
+ [
+ PutStringLn<'Other stuff?'>,
- Test<"should do some other stuff", [
- Assert<Equals<[1, 2, 3], [1, 2, 3]>>,
- ]>,
+ Test<'should do some other stuff', [Assert<Equals<[1, 2, 3], [1, 2, 3]>>]>
- // Test<"this'll fail fo sho", [
- // Assert<Equals<[1, 2, 3], [4, 5, 6]>>,
- // ]>,
-]>
+ // Test<"this'll fail fo sho", [
+ // Assert<Equals<[1, 2, 3], [4, 5, 6]>>,
+ // ]>,
+ ]
+>
export type main = [
// Update env to node with test helpers
SetEvalEnvironment<'test.node'>,
- PutStringLn<"=== Running tests... ===\n">,
+ PutStringLn<'=== Running tests... ===\n'>,
testSomeStuff,
- testSomeMoreStuff,
+ testSomeMoreStuff
]
diff --git a/src/context.ts b/src/context.ts
index 485083a..06fe041 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -61,12 +61,12 @@ export const createContext = (options: CtxOptions): Ctx => {
const getTypeValue = (ty: Type | undefined): any => {
try {
return JSON.parse(typeToString(ty))
- } catch(_) {
+ } catch (_) {
return null
}
}
- const refMap: Map<string, string> = new Map
+ const refMap: Map<string, string> = new Map()
const createRef = (ty: string): string => {
const key = uuid()
refMap.set(key, ty)
@@ -83,7 +83,9 @@ export const createContext = (options: CtxOptions): Ctx => {
typeToString,
getTypeValue,
- get currentEnv() { return currentEnv },
+ get currentEnv() {
+ return currentEnv
+ },
setEnv,
createRef,
diff --git a/src/eval-env/builtins.ts b/src/eval-env/builtins.ts
index f9c4ce8..7e00253 100644
--- a/src/eval-env/builtins.ts
+++ b/src/eval-env/builtins.ts
@@ -1,143 +1,145 @@
import { Type } from 'ts-morph'
-import { Ctx } from "../types"
+import { Ctx } from '../types'
import { evalList } from '../util'
export default (ctx: Ctx, args: Type[]) => ({
- SetEvalEnvironment: async () => {
- ctx.setEnv(ctx.getTypeValue(args[0]))
- return []
- },
+ SetEvalEnvironment: async () => {
+ ctx.setEnv(ctx.getTypeValue(args[0]))
+ return []
+ },
- DefineEffect: async () => {
- const [nameTyp, exprTyp] = args
- const name = nameTyp?.getLiteralValue() as string
- const exprStr = exprTyp?.getLiteralValue() as string
+ DefineEffect: async () => {
+ const [nameTyp, exprTyp] = args
+ const name = nameTyp?.getLiteralValue() as string
+ const exprStr = exprTyp?.getLiteralValue() as string
- ctx.addCustomEffect(name, exprStr)
- return []
- },
+ ctx.addCustomEffect(name, exprStr)
+ return []
+ },
- CreateRef: async () => {
- const val = ctx.typeToString(args[0])
- const refKey = ctx.createRef(val)
- const [resultKey, _] = ctx.createResult(JSON.stringify(refKey))
- return [resultKey]
- },
+ CreateRef: async () => {
+ const val = ctx.typeToString(args[0])
+ const refKey = ctx.createRef(val)
+ const [resultKey, _] = ctx.createResult(JSON.stringify(refKey))
+ return [resultKey]
+ },
- GetRef: async () => {
- const refKey = ctx.getTypeValue(args[0])
- const val = ctx.getRef(refKey)
- if (!val) throw new Error('Ref has been deleted')
- const [resultKey, _] = ctx.createResult(val)
- return [resultKey]
- },
+ GetRef: async () => {
+ const refKey = ctx.getTypeValue(args[0])
+ const val = ctx.getRef(refKey)
+ if (!val) throw new Error('Ref has been deleted')
+ const [resultKey, _] = ctx.createResult(val)
+ return [resultKey]
+ },
- SetRef: async () => {
- const [ keyTy, valTyp ] = args
- ctx.setRef(ctx.getTypeValue(keyTy), ctx.typeToString(valTyp))
- return []
- },
+ SetRef: async () => {
+ const [keyTy, valTyp] = args
+ ctx.setRef(ctx.getTypeValue(keyTy), ctx.typeToString(valTyp))
+ return []
+ },
- DeleteRef: async () => {
- ctx.deleteRef(ctx.getTypeValue(args[0]))
- return []
- },
+ DeleteRef: async () => {
+ ctx.deleteRef(ctx.getTypeValue(args[0]))
+ return []
+ },
- Pure: async () => {
- const [valTyp] = args
- const [resultKey, _] = ctx.createResult(ctx.typeToString(valTyp))
- return [resultKey]
- },
+ Pure: async () => {
+ const [valTyp] = args
+ const [resultKey, _] = ctx.createResult(ctx.typeToString(valTyp))
+ return [resultKey]
+ },
- Print: async () => {
- console.log(...args.map(ctx.typeToString))
- return []
- },
+ Print: async () => {
+ console.log(...args.map(ctx.typeToString))
+ return []
+ },
- PutString: async () => {
- const [strinTyp] = args
- const typString = ctx.getTypeValue(strinTyp) ?? ctx.typeToString(strinTyp)
- process.stdout.write(typString)
- return []
- },
+ PutString: async () => {
+ const [strinTyp] = args
+ const typString = ctx.getTypeValue(strinTyp) ?? ctx.typeToString(strinTyp)
+ process.stdout.write(typString)
+ return []
+ },
- Debug: async () => {
- const [labelTyp, valueTyp] = args
- const label = ctx.getTypeValue(labelTyp)
- const value = ctx.typeToString(valueTyp)
- console.log(label, value)
- const [resultKey, _] = ctx.createResult(JSON.stringify(value))
- return [resultKey]
- },
+ Debug: async () => {
+ const [labelTyp, valueTyp] = args
+ const label = ctx.getTypeValue(labelTyp)
+ const value = ctx.typeToString(valueTyp)
+ console.log(label, value)
+ const [resultKey, _] = ctx.createResult(JSON.stringify(value))
+ return [resultKey]
+ },
- Bind: async () => {
- const [inputTyp, chainToKind] = args
- const [resultKey] = inputTyp ? await ctx.evaluateType(ctx, inputTyp) : []
+ Bind: async () => {
+ const [inputTyp, chainToKind] = args
+ const [resultKey] = inputTyp ? await ctx.evaluateType(ctx, inputTyp) : []
- // TODO: Handle resultKey undefined case
- const [_, compNode] = ctx.createResult(
- `(${ctx.typeToString(chainToKind)} & { input: (${ctx.getResultExpr(
- resultKey
- )})['output'] })['return']`
- )
- // TODO: Avoid using getTypeAtLocation?
- const compTyp = compNode
- ?.getType()
- .getProperty('output')
- ?.getTypeAtLocation(ctx.entryPoint)
+ // TODO: Handle resultKey undefined case
+ const [_, compNode] = ctx.createResult(
+ `(${ctx.typeToString(chainToKind)} & { input: (${ctx.getResultExpr(
+ resultKey
+ )})['output'] })['return']`
+ )
+ // TODO: Avoid using getTypeAtLocation?
+ const compTyp = compNode
+ ?.getType()
+ .getProperty('output')
+ ?.getTypeAtLocation(ctx.entryPoint)
- return compTyp ? await ctx.evaluateType(ctx, compTyp) : []
- },
+ return compTyp ? await ctx.evaluateType(ctx, compTyp) : []
+ },
- Try: async () => {
- const [effTyp, catchK] = args
+ Try: async () => {
+ const [effTyp, catchK] = args
- try {
- if (!effTyp) throw new Error('wow')
- return await ctx.evaluateType(ctx, effTyp)
- } catch(e) {
- const error = JSON.stringify((e as any)?.message ?? e)
- const catchResExpr = `(${ctx.typeToString(catchK)} & { input: ${error} })['return']`
- const [resultKey, _] = ctx.createResult(catchResExpr)
- return [resultKey]
- }
- },
+ try {
+ if (!effTyp) throw new Error('wow')
+ return await ctx.evaluateType(ctx, effTyp)
+ } catch (e) {
+ const error = JSON.stringify((e as any)?.message ?? e)
+ const catchResExpr = `(${ctx.typeToString(
+ catchK
+ )} & { input: ${error} })['return']`
+ const [resultKey, _] = ctx.createResult(catchResExpr)
+ return [resultKey]
+ }
+ },
- Throw: async () => {
- throw args[0] && ctx.getTypeValue(args[0])
- },
+ Throw: async () => {
+ throw args[0] && ctx.getTypeValue(args[0])
+ },
- JsExpr: async () => {
- const [exprTyp] = args
- const exprStr = ctx.getTypeValue(exprTyp)
- const result = eval(`JSON.stringify(${exprStr})`)
- const [resultKey, _] = ctx.createResult(`${result}`)
- return [resultKey]
- },
+ JsExpr: async () => {
+ const [exprTyp] = args
+ const exprStr = ctx.getTypeValue(exprTyp)
+ const result = eval(`JSON.stringify(${exprStr})`)
+ const [resultKey, _] = ctx.createResult(`${result}`)
+ return [resultKey]
+ },
- Seq: async () => {
- const [effectTyps] = args
- const effectResults = await evalList(
- ctx,
- effectTyps?.getTupleElements() ?? []
- )
- const [resultKey, _] = ctx.createResult(`[
+ Seq: async () => {
+ const [effectTyps] = args
+ const effectResults = await evalList(
+ ctx,
+ effectTyps?.getTupleElements() ?? []
+ )
+ const [resultKey, _] = ctx.createResult(`[
${effectResults.map(ctx.getResultExpr).join(', ')}
]`)
- return [resultKey]
- },
+ return [resultKey]
+ },
- Do: async () => {
- const [effectTyps] = args
- const effectResults = await evalList(
- ctx,
- effectTyps?.getTupleElements() ?? []
- )
- // TODO: Use last type's result instead of last result key
- const lastResKey = effectResults[effectResults.length - 1]
- const [resultKey, _] = ctx.createResult(
- `(${ctx.getResultExpr(lastResKey)})['output']`
- )
- return [resultKey]
- },
+ Do: async () => {
+ const [effectTyps] = args
+ const effectResults = await evalList(
+ ctx,
+ effectTyps?.getTupleElements() ?? []
+ )
+ // TODO: Use last type's result instead of last result key
+ const lastResKey = effectResults[effectResults.length - 1]
+ const [resultKey, _] = ctx.createResult(
+ `(${ctx.getResultExpr(lastResKey)})['output']`
+ )
+ return [resultKey]
+ },
})
diff --git a/src/eval-env/test.ts b/src/eval-env/test.ts
index eddf366..84ae138 100644
--- a/src/eval-env/test.ts
+++ b/src/eval-env/test.ts
@@ -12,7 +12,7 @@ export default (ctx: Ctx, args: Type[]) => ({
}
console.log('[✓]')
- } catch(e) {
+ } catch (e) {
console.log('[TEST FAILED]')
throw e
}
diff --git a/src/eval.ts b/src/eval.ts
index 2b93e49..d7055a3 100644
--- a/src/eval.ts
+++ b/src/eval.ts
@@ -5,8 +5,8 @@ import { Ctx } from './types'
import * as builtins from './eval-env/builtins'
type EffDefn = {
- default: (ctx: Ctx, args: Type[]) => Record<string, () => Promise<string[]>>,
- cleanup?: () => void,
+ default: (ctx: Ctx, args: Type[]) => Record<string, () => Promise<string[]>>
+ cleanup?: () => void
}
const mergeEffDefns = (a: EffDefn, b: EffDefn): EffDefn => ({
default: (ctx: Ctx, args: Type[]) => ({
@@ -20,7 +20,7 @@ const mergeEffDefns = (a: EffDefn, b: EffDefn): EffDefn => ({
})
const cleanupActions = new Set<undefined | (() => void)>()
-export const cleanup = () => cleanupActions.forEach(f => f?.())
+export const cleanup = () => cleanupActions.forEach((f) => f?.())
let prevEnv: string
@@ -37,16 +37,20 @@ export const evaluateType = async (
const envDefns = await match(ctx.currentEnv, {
node: () => import('./eval-env/node') as Promise<EffDefn>,
- 'test.node': async () => mergeEffDefns(
- await import('./eval-env/test'),
- await import('./eval-env/node'),
- ),
+ 'test.node': async () =>
+ mergeEffDefns(
+ await import('./eval-env/test'),
+ await import('./eval-env/node')
+ ),
_: async () => {
throw new Error(`Invalid env: ${ctx.currentEnv}`)
},
})
- const { default: envEffects, cleanup } = mergeEffDefns(builtins as unknown as EffDefn, envDefns)
+ const { default: envEffects, cleanup } = mergeEffDefns(
+ builtins as unknown as EffDefn,
+ envDefns
+ )
// Update cleanup if env has changed
if (prevEnv !== ctx.currentEnv) {
diff --git a/src/index.ts b/src/index.ts
index a144c57..f6d46d6 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -6,7 +6,9 @@ import { evalList } from './util'
const main = () => {
program
.name('ts-types-lang')
- .description(`A runtime for typescript's type system that turns it into a general purpose, purely functional programming language!`)
+ .description(
+ `A runtime for typescript's type system that turns it into a general purpose, purely functional programming language!`
+ )
program
.command('run')
@@ -24,5 +26,4 @@ const main = () => {
return program.parseAsync()
}
-main()
- .finally(() => cleanup())
+main().finally(() => cleanup())
diff --git a/src/types.ts b/src/types.ts
index d9e874e..c0258db 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -17,13 +17,13 @@ export interface Ctx {
getResultExpr: (key?: string) => string
printResultNode: () => void
- currentEnv: string,
- setEnv: (e: string) => void,
+ currentEnv: string
+ setEnv: (e: string) => void
- createRef: (ty: string) => string,
- getRef: (key: string) => any,
- setRef: (key: string, ty: string) => void,
- deleteRef: (key: string) => void,
+ createRef: (ty: string) => string
+ getRef: (key: string) => any
+ setRef: (key: string, ty: string) => void
+ deleteRef: (key: string) => void
addCustomEffect: (name: string, expr: string) => void
runCustomEffect: (name: string, args: Type[]) => Promise<string[]>
diff --git a/src/util.ts b/src/util.ts
index 13bdb35..f7bb20a 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -1,5 +1,5 @@
-import { Type } from "ts-morph"
-import { Ctx } from "./types"
+import { Type } from 'ts-morph'
+import { Ctx } from './types'
export const match = <K extends string, R>(
k: K | undefined,
diff --git a/stdlib/effect.ts b/stdlib/effect.ts
index 9fe3216..5ae9cd9 100644
--- a/stdlib/effect.ts
+++ b/stdlib/effect.ts
@@ -14,4 +14,3 @@ export interface Seq<_Effs extends Effect[]> extends Effect {}
export interface Do<_Effs extends Effect[]> extends Effect {}
export interface Pure<V> extends Effect<V> {}
-
diff --git a/stdlib/exception.ts b/stdlib/exception.ts
index 731b3b0..ddb980c 100644
--- a/stdlib/exception.ts
+++ b/stdlib/exception.ts
@@ -1,4 +1,4 @@
-import { Effect, Kind1 } from "./effect";
+import { Effect, Kind1 } from './effect'
export interface Try<_E extends Effect, _Catch extends Kind1> extends Effect {}
diff --git a/stdlib/nat.ts b/stdlib/nat.ts
index 4334a30..52877c1 100644
--- a/stdlib/nat.ts
+++ b/stdlib/nat.ts
@@ -3,16 +3,19 @@ export type Zero = { _prev: null }
export type Succ<N extends Nat> = { _prev: N }
export type Pred<N extends Nat> = N extends Zero ? Zero : N['_prev']
-export type Add<A extends Nat, B extends Nat> =
- A extends Zero ? B : Add<Pred<A>, Succ<B>>
+export type Add<A extends Nat, B extends Nat> = A extends Zero
+ ? B
+ : Add<Pred<A>, Succ<B>>
-export type ToNumber<N extends Nat, Acc extends 0[] = []> =
- N extends Zero ? Acc['length']
- : ToNumber<Pred<N>, [...Acc, 0]>
+export type ToNumber<N extends Nat, Acc extends 0[] = []> = N extends Zero
+ ? Acc['length']
+ : ToNumber<Pred<N>, [...Acc, 0]>
-export type FromNumber<N extends number, Res extends Nat = Zero, Acc extends 0[] = []> =
- N extends Acc['length'] ? Res
- : FromNumber<N, Succ<Res>, [...Acc, 0]>
+export type FromNumber<
+ N extends number,
+ Res extends Nat = Zero,
+ Acc extends 0[] = []
+> = N extends Acc['length'] ? Res : FromNumber<N, Succ<Res>, [...Acc, 0]>
export type _0 = Zero
export type _1 = Succ<_0>
diff --git a/stdlib/stdio.ts b/stdlib/stdio.ts
index 56b546d..b1e205b 100644
--- a/stdlib/stdio.ts
+++ b/stdlib/stdio.ts
@@ -8,7 +8,6 @@ export interface Debug<_ extends string, T> extends Effect<T> {}
export interface ReadLine extends Effect<string> {}
-export type PutStringLn<S extends string> =
- S extends infer S extends string
- ? PutString<`${S}\n`>
- : never
+export type PutStringLn<S extends string> = S extends infer S extends string
+ ? PutString<`${S}\n`>
+ : never
diff --git a/stdlib/sys.ts b/stdlib/sys.ts
index 9fff7a9..0b48fa8 100644
--- a/stdlib/sys.ts
+++ b/stdlib/sys.ts
@@ -9,7 +9,8 @@ export interface JsExpr<_Expr extends string> extends Effect<any> {}
export interface DefineEffect<_Name extends string, _Func extends string>
extends Effect {}
-export interface Exit<_ extends number | undefined = undefined> extends Effect {}
-
-export interface SetEvalEnvironment<_Env extends 'test.node' | 'node'> extends Effect {}
+export interface Exit<_ extends number | undefined = undefined>
+ extends Effect {}
+export interface SetEvalEnvironment<_Env extends 'test.node' | 'node'>
+ extends Effect {}
diff --git a/stdlib/test.ts b/stdlib/test.ts
index 7497f7b..639c433 100644
--- a/stdlib/test.ts
+++ b/stdlib/test.ts
@@ -1,4 +1,4 @@
-import { Effect } from "./effect";
+import { Effect } from './effect'
export interface Config {
compileTimeTestFailures: false
@@ -7,5 +7,6 @@ export interface Config {
type Assertion = Config['compileTimeTestFailures'] extends true ? true : boolean
-export interface Assert<_B extends Assertion> extends Effect { }
-export interface Test<_m extends string, _effs extends Effect[]> extends Effect { }
+export interface Assert<_B extends Assertion> extends Effect {}
+export interface Test<_m extends string, _effs extends Effect[]>
+ extends Effect {}
diff --git a/stdlib/util.ts b/stdlib/util.ts
index 4851392..20a41fb 100644
--- a/stdlib/util.ts
+++ b/stdlib/util.ts
@@ -21,8 +21,10 @@ export type ADT<D extends Record<string, any>> = {
? { t: Rec[keyof Rec] } & { [k in keyof Rec]: ADTConstructor<Rec[k]> }
: never
-export type Equals<Left, Right> =
- [Left] extends [Right] ? ([Right] extends [Left] ? true : false) : false
+export type Equals<Left, Right> = [Left] extends [Right]
+ ? [Right] extends [Left]
+ ? true
+ : false
+ : false
export type Not<B extends boolean> = B extends true ? false : true
-