Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

allow type parameters on type arguments #5959

Closed
zpdDG4gta8XKpMCd opened this issue Dec 6, 2015 · 6 comments
Closed

allow type parameters on type arguments #5959

zpdDG4gta8XKpMCd opened this issue Dec 6, 2015 · 6 comments
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript

Comments

@zpdDG4gta8XKpMCd
Copy link

interface Map<a> {
   [key: string]: a;
}

// IMPORTANT: here my intention is that the `read` and `run` methods are agreed on using the same type parameter
interface Command<Options> {
   read(args: string[]): Options;
   run(options: Options): void;
};

interface CopyCommandOptions {
   from: string;
   to:  string;
}

interface CleanCommandOptions {
   directory: string;
   pattern: string;
}


// currently in TypeScript there are 2 options to to declare `knownCommands` below:
// - Map<Command<any>> which contaminates my code with `any`
// - Map<Command<CopyCommandOptions | CleanCommandOptions>> which has different semantics
// ideally I wish I could declare it like this:
let knownCommands : Map<<a>Command<a>> = { // <-- hypothetical syntax
    'copy': <Command<CopyCommandOptions>> undefined,
    'clean': <Command<CleanCommandOptions>> undefined
};

// so that later I could the following do in a type safe manner:
let command = knownCommands[name];
command.run(command.read(args));
@zpdDG4gta8XKpMCd zpdDG4gta8XKpMCd changed the title allow type parameters on anonymous types allow type parameters on type parameters Dec 6, 2015
@zpdDG4gta8XKpMCd zpdDG4gta8XKpMCd changed the title allow type parameters on type parameters allow type parameters on type arguments Dec 6, 2015
@DanielRosenwasser
Copy link
Member

Note for others that this is not the same as #1213. The idea on this issue is that there is a constraint on the generic type, but that the type arguments themselves should be inferred.

This is similar to the desired behavior in #5652.

@DanielRosenwasser DanielRosenwasser added the Suggestion An idea for TypeScript label Dec 6, 2015
@mhegazy mhegazy added the Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. label Dec 10, 2015
@LiamGoodacre
Copy link

From reading your example, it looks to me like you're wanting existential types?

Keep in mind that I haven't really done any typescript before - so there's likely a nicer way to do what I came up with:

type Exists =
    <r> (go : <t> (_ : Command<t>) => r) => r

const exists = <c> (command : Command<c>) : Exists =>
    <r> (go : <t> (_ : Command<t>) => r) : r => go(command)

let knownCommands : Map<Exists> = {
    'copy': exists(<Command<CopyCommandOptions>> undefined),
    'clean': exists(<Command<CleanCommandOptions>> undefined)
};

let args : string[]
knownCommands[name](<t> (command : Command<t>) => {
    command.run(command.read(args));
});

Does that roughly do what you want in this case? @Aleksey-Bykov

@zpdDG4gta8XKpMCd
Copy link
Author

@LiamGoodacre
This is a neat trick. Didn't realize I could do it this way. Yes, it looks like existential types is the name of what I've been looking for, which now can be googled and read about closely. Thanks.

@LiamGoodacre
Copy link

😄 Also to highlight that the read/run types match up:

knownCommands[a](<t> (x : Command<t>) => {
    knownCommands[b]<s> (y : Command<s>) => {
        //x.run(y.read(args)); // type error, `s` is not `t`
        //y.run(x.read(args)); // type error, `t` is not `s`
        x.run(x.read(args)); // fine
        y.run(y.read(args)); // fine
    });
});

@LiamGoodacre
Copy link

This may be useful as an example of existential types as a library: https://github.com/purescript/purescript-exists/blob/master/docs/Data/Exists.md

@RyanCavanaugh
Copy link
Member

This hasn't gotten a concrete proposal yet and I imagine there are more well-fleshed-out issues on it by now

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Proposal This issue needs a plan that clarifies the finer details of how it could be implemented. Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

5 participants