refactor: Convenience type operator for specifying concrete signatures
This commit is contained in:
parent
1eb73be2fa
commit
d55776655f
@ -19,9 +19,10 @@ export const Complex_type = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type Binary<B> = [B, B]
|
|
||||||
|
|
||||||
export interface ComplexReturn<Params> {
|
export interface ComplexReturn<Params> {
|
||||||
|
// Sadly, I can't think of a way to make some nice abbreviation operators
|
||||||
|
// for these generic type specifications because TypeScript generics
|
||||||
|
// can't take and use generic parameters, only fully instantiated types.
|
||||||
complex: Params extends [infer U] ? Complex<U> // unary case
|
complex: Params extends [infer U] ? Complex<U> // unary case
|
||||||
: Params extends BBinary<infer B> ? Complex<B> // binary case
|
: Params extends BBinary<infer B> ? Complex<B> // binary case
|
||||||
: never
|
: never
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
type TypeName = string
|
type TypeName = string
|
||||||
type Parameter = TypeName
|
type Parameter = TypeName
|
||||||
type Signature = Parameter[]
|
type InputSignature = Parameter[]
|
||||||
type DependenciesType = Record<string, Function>
|
type DependenciesType = Record<string, Function>
|
||||||
|
|
||||||
export type typeOfDependency = {typeOf: (x: unknown) => TypeName}
|
export type typeOfDependency = {typeOf: (x: unknown) => TypeName}
|
||||||
@ -62,7 +62,11 @@ export interface ReturnTypes<Params> {}
|
|||||||
|
|
||||||
// Helpers for specifying signatures
|
// Helpers for specifying signatures
|
||||||
|
|
||||||
// A homogenous binary operation (comes up a lot)
|
// A basic signature with concrete types
|
||||||
|
export type Signature<CandidateParams, ActualParams, Returns> =
|
||||||
|
CandidateParams extends ActualParams ? Returns : never
|
||||||
|
|
||||||
|
// A homogenous binary operation (comes up a lot, needs a better name?)
|
||||||
// Typical usage: `foo_impl: Params extends BBinary<infer B> ? B : never`
|
// Typical usage: `foo_impl: Params extends BBinary<infer B> ? B : never`
|
||||||
// says that this implementation takes two arguments, both of type B, and
|
// says that this implementation takes two arguments, both of type B, and
|
||||||
// returns the same type.
|
// returns the same type.
|
||||||
@ -118,9 +122,9 @@ type SpecificationsGroup = Record<string, SpecObject>
|
|||||||
export class Dispatcher {
|
export class Dispatcher {
|
||||||
installSpecification(
|
installSpecification(
|
||||||
name: string,
|
name: string,
|
||||||
signature: Signature,
|
signature: InputSignature,
|
||||||
returns: TypeName,
|
returns: TypeName,
|
||||||
dependencies: Record<string, Signature>,
|
dependencies: Record<string, InputSignature>,
|
||||||
behavior: Function // possible todo: constrain this type based
|
behavior: Function // possible todo: constrain this type based
|
||||||
// on the signature, return type, and dependencies. Not sure if
|
// on the signature, return type, and dependencies. Not sure if
|
||||||
// that's really possible, though.
|
// that's really possible, though.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import {configDependency} from '../core/Config.js'
|
import {configDependency} from '../core/Config.js'
|
||||||
import {BBinary, Dependency, ImpType} from '../core/Dispatcher.js'
|
import {Signature, Dependency, ImpType} from '../core/Dispatcher.js'
|
||||||
import type {Complex} from '../Complex/type.js'
|
import type {Complex} from '../Complex/type.js'
|
||||||
|
|
||||||
declare module "./type" {
|
declare module "./type" {
|
||||||
@ -7,7 +7,7 @@ declare module "./type" {
|
|||||||
// This description loses information: some subtypes like NumInt or
|
// This description loses information: some subtypes like NumInt or
|
||||||
// Positive are closed under addition, but this says that the result
|
// Positive are closed under addition, but this says that the result
|
||||||
// of add is just a number, not still of the reduced type
|
// of add is just a number, not still of the reduced type
|
||||||
add: Params extends BBinary<number> ? number : never
|
add: Signature<Params, [number, number], number>
|
||||||
// Whereas this one would preserve information, but would lie
|
// Whereas this one would preserve information, but would lie
|
||||||
// because it claims all subtypes of number are closed under addition,
|
// because it claims all subtypes of number are closed under addition,
|
||||||
// which is not true for `1 | 2 | 3`, for example.
|
// which is not true for `1 | 2 | 3`, for example.
|
||||||
@ -16,15 +16,15 @@ declare module "./type" {
|
|||||||
// : never
|
// : never
|
||||||
//
|
//
|
||||||
// Not sure how this will need to go when we introduce NumInt.
|
// Not sure how this will need to go when we introduce NumInt.
|
||||||
unaryMinus: Params extends [number] ? number : never
|
unaryMinus: Signature<Params, [number], number>
|
||||||
subtract: Params extends BBinary<number> ? number : never
|
subtract: Signature<Params, [number, number], number>
|
||||||
multiply: Params extends BBinary<number> ? number : never
|
multiply: Signature<Params, [number, number], number>
|
||||||
divide: Params extends BBinary<number> ? number : never
|
divide: Signature<Params, [number, number], number>
|
||||||
// Best we can do for sqrt at compile time, since actual return
|
// Best we can do for sqrt at compile time, since actual return
|
||||||
// type depends on config. Not sure how this will play out
|
// type depends on config. Not sure how this will play out
|
||||||
// when we make a number-only bundle, but at least the import type
|
// when we make a number-only bundle, but at least the import type
|
||||||
// above for Complex<> does not lead to any emitted JavaScript.
|
// above for Complex<> does not lead to any emitted JavaScript.
|
||||||
sqrt: Params extends [number] ? (number | Complex<number>) : never
|
sqrt: Signature<Params, [number], number | Complex<number>>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,10 @@ export interface NumbersReturn<Params> {
|
|||||||
zero: Params extends [infer T]
|
zero: Params extends [infer T]
|
||||||
? T extends number ? 0 extends T ? 0 : never : never
|
? T extends number ? 0 extends T ? 0 : never : never
|
||||||
: never
|
: never
|
||||||
|
// Note that in any case the simple
|
||||||
|
// zero: Signature<Params, [number], 0>
|
||||||
|
// makes complex fail to compile, because it worries that you might be
|
||||||
|
// making `Complex<Small>` where zero would not return the right type.
|
||||||
}
|
}
|
||||||
|
|
||||||
export const zero: ImpType<'zero', [number]> = a => 0
|
export const zero: ImpType<'zero', [number]> = a => 0
|
||||||
|
Loading…
Reference in New Issue
Block a user