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

Truly "empty" type constructors? (Disallow passing arguments) #44

Open
joshburgess opened this issue Sep 13, 2018 · 7 comments
Open

Truly "empty" type constructors? (Disallow passing arguments) #44

joshburgess opened this issue Sep 13, 2018 · 7 comments

Comments

@joshburgess
Copy link

joshburgess commented Sep 13, 2018

Hi, I was recently playing around with unionize and discovered that using {} to represent members of the union which take no arguments doesn't actually prevent you from passing arguments through in the functions passed to match via the type constructors. I think, ideally, you would receive a type error when trying to pass any argument at all due to that being the intention of modeling a simple, "empty" type.

Do you have any ideas for how this could be made to work? Is it possible?

@OliverJAsh
Copy link
Collaborator

Maybe the never type?

@joshburgess
Copy link
Author

I tried never and it asked me to provide an argument of type never (like pass it anything and cast to never).

Maybe, I misused it somehow?

@pelotom
Copy link
Owner

pelotom commented Sep 13, 2018

Ah, yeah, that won't work, because then you'd never be able to construct an instance of that variant.

This is a tricky issue. As usual structural typing is a double-edged sword. Sometimes it's useful that a function with a top type as argument (or no argument) can accept any input... other times you want to be warned that you're throwing away information. I'm not sure what the right answer is.

@joshburgess
Copy link
Author

joshburgess commented Sep 18, 2018

I ran into this same issue (well, similar) in some code I've been writing based on some ideas by gcanti (fp-ts). It wasn't exactly the same, but it was similar in that types with nothing but a tag (no additional props) introduced a never type into the mix, which forced type constructors which should have no params to ask for a param.

I was able to solve it by using conditional typing and an Exact utility which did some comparison to find where never is introduced and return a function which takes no params in that case, while leaving the other branch of the logic the same as before.

I think we could probably do something similar with unionize. Basically, we'd modify the bit that builds the constructor functions and explicitly look for that never type, or any other designated type we want to use for this purpose, and do something different in response to it.

I think using never is fine, but the library could instead provide it's own custom type specifically for creating types which have constructors with no args.... maybe, Empty or Valueless or something like that?

@pelotom
Copy link
Owner

pelotom commented Sep 18, 2018

@joshburgess I'd need to see a more concrete proposal for what you have in mind, it's all a bit abstract to me right now.

@joshburgess
Copy link
Author

@pelotom No prob. As soon as I'm done with what I'm working on I'll clone unionize and try to implement the same idea to demonstrate.

@OliverJAsh
Copy link
Collaborator

@joshburgess Where did you get to on this?

Essentially the problem I think we're trying to solve is this, right?

declare const constructor: (type: {}) => any
// no error!!
constructor({ foo: 1 })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants