javascript - Typescript-definisjon for union-type js


Vil gjerne få hjelp til å skrive d.ts-fil for https://github.com/paldepind/union-type

Med unionstypen nedenfor,

let Maybe = Type({
    Nothing: []
    , Just: [Number]
})

Jeg ville elsket å se en kompilatorfeil hvis Maybe.Nothing() blir feilstavet som Maybe.None()

Jeg prøvde å hente nøklene fra objektliteralet, men kompilatoren klarer fortsatt ikke å gjenkjenne Nothing og Just i den resulterende typen Maybe.

interface Obj {
    prototype: any
    case: (x: {[index: string]: (...args) => any}) => any
    caseOn: (x: {[index: string]: (...args) => any}) => any
}
interface Union<T> {
    (desc: T): T & Obj
}
var Type: Union<{[key: string]: any}>
export = Type

Svar #1

Jeg tror det du leter etter er Indekstype, se Avanserte typer-seksjonen i håndboken for en forklaring på hvordan de fungerer. Jeg har også laget en deklarasjonsfil for paldepind/union-type, men den er ufullstendig :

declare module 'union-type' {
  type Constructors =
    | StringConstructor
    | NumberConstructor
    | ArrayConstructor
    | BooleanConstructor
    | ObjectConstructor
    | FunctionConstructor

  export default function Type<
    T extends {
      [k: string]: (Constructors | ((arg?: any) => boolean | Constructors))[]
    },
    K extends keyof T
  >(
    desc: T
  ): {
    // case(cases: { [k in K]: (...args: any[]) => void }, obj: any): void
    [k in K]: (...args: any[]) => any
  }
}

Jeg prøver også å finne en løsning for det biblioteket i TS...

Svar #2

Hvis du leter etter en Maybe-implementering, her er en jeg skrev en gang i tiden

/**
 * A Maybe implementation
 * that is JavaScript first
 * i.e. simple typed abstraction over null/undefined
 */
export class Maybe<T>{
    private _value: T;
    /** Based on value it will be Some or None */
    constructor(value: T) {
        this._value = value;
    }
    /** Shorthand for constructor */
    static Some<T>(value: T): Maybe<T> {
        if (value === null || value === undefined) {
            throw new Error('value for some cannot be null or undefied');
        }
        return new Maybe(value);
    };
    static None<T>(): Maybe<T> {
        return new Maybe(null);
    };
    get value(): T {
        return this._value;
    }
    get isSome() {
        return this._value !== null && this._value !== undefined;
    }
    get isNone() {
        return !this.isSome;
    }
    map<U>(mapper: (now: T) => U): Maybe<U> {
        if (this.isSome) {
            return new Maybe(mapper(this._value));
        }
        else {
            return new Maybe(null);
        }
    }
}

Det sagt, jeg synes det er ganske ubrukelig, mye enklere å bare være oppmerksom på null/undefined og bruke valid-egenskapen på objektene dine (mer https://medium.com/@basarat/null-vs-undefined-in-typescript-land-dc0c7a5f240a)

Mer

Når det er sagt, kommer TypeScript til å få førsteklasses nullability-støtte https://github.com/Microsoft/TypeScript/pull/7140, og du vil kunne gjøre number | null | undefined, og du vil ikke få lov til å tilordne null til et tall, det vil si let foo:number=null;/Feil, foo er ikke nullable