Skip to content
New issue

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

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

Already on GitHub? # 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

# for free to join this conversation on GitHub. Already have an account? # 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