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 values other than classes and functions #20015

Closed
zpdDG4gta8XKpMCd opened this issue Nov 14, 2017 · 8 comments
Closed
Labels
Duplicate An existing issue was already created

Comments

@zpdDG4gta8XKpMCd
Copy link

i can do this:

function getter<T extends { value: U}, U>(data: T): U {
    return data.value;
}

but i cannot do this:

interface Accessor<T extends { value: U; }, U> {
    get(data: T): U;
    set(data: T, value: U): T;
}

const accessor: Accessor = { // <-- error, requires type arguments that i don"t have yet
    get: data => data.value,
    set: (data, value) => ({ ... data, value })
}

i wish i could do something like this:

const accessor<T extends { value: U; }, U>: Accessor<T, U> = {
    get: data => data.value,
    set: (data, value) => ({ ... data, value })
}

consider allowing type parameters on values other than functions and classes

@mhegazy
Copy link
Contributor

mhegazy commented Nov 14, 2017

then how would T and U be known when accessor is used? do you have to specify accessor<number, string> or you imagine some sort of inference taking place? if so how?

@zpdDG4gta8XKpMCd
Copy link
Author

zpdDG4gta8XKpMCd commented Nov 14, 2017

just in the exact same way as it is for functions:

  1. yes, one way it to explicitly set them accessor<string, number>.get(xxx)
  2. yes, another way is to let the inference guess: takeAccessor(accessor)

@mhegazy
Copy link
Contributor

mhegazy commented Nov 14, 2017

does that happen on every use? or the first, then it is fixed? functions and classes guarantee that each invocation is isolated from the other, but that is not the same as a variable, assuming there is a state involved.. e.g. can i

var x: number;
accessor.set({ value: "string" } );
x = accessor.get();

@zpdDG4gta8XKpMCd
Copy link
Author

zpdDG4gta8XKpMCd commented Nov 14, 2017

just like with the functions where type arguments are required on each call, the arguments for values need to be provided or inferred at each reading (dereferencing)

so yes it needs to happen on every use

@zpdDG4gta8XKpMCd
Copy link
Author

zpdDG4gta8XKpMCd commented Nov 14, 2017

in fact at the moment i use functions to do exactly that:

function alwaysAccesorOf<T, U>(): Accessor<T, U> {
   return {
      get: data => data.value,
      set: (data, value) => ({ ...data, value })
   };
}

alwaysAccessorOf<string, number>().get(xxx) // <-- i wish i could avoid a function call just
                                            // for the sake of providing type arguments
                                            // and simply do:

accessor<string, number>.get(xxx);

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Nov 14, 2017

👍
I run into this fairly often.

Related issues:
#19728
#17574

@mhegazy
Copy link
Contributor

mhegazy commented Nov 14, 2017

also related to #15877

@mhegazy mhegazy added the Suggestion An idea for TypeScript label Nov 14, 2017
@RyanCavanaugh RyanCavanaugh added Duplicate An existing issue was already created and removed Suggestion An idea for TypeScript labels Aug 22, 2018
@RyanCavanaugh
Copy link
Member

Tracking at #17574

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants