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

regl.prop type definition error: Argument of type 'string' is not assignable to parameter of type 'never'. [2345] #602

Open
kevzettler opened this issue Feb 9, 2021 · 5 comments

Comments

@kevzettler
Copy link
Contributor

I'm seeing a TypeScript error from regl.prop that I haven't encountered before.

Argument of type 'string' is not assignable to parameter of type 'never'. [2345]

I am able to reproduce in a Sandbox using the example from the regl README.md

The error stems from:

regl/regl.d.ts

Line 139 in f95aac9

prop<Props extends {}, Key extends keyof Props>(name: Key): DynamicVariable<Props[Key]>;

I'm not sure how this type is intended to work because it looks like Key extends keyof Props will aways return never

I feel like i've used this without encountering the error before. i'm on tsc -v Version 4.1.3

@jcwilk
Copy link

jcwilk commented Feb 28, 2021

Just ran into this too, would love it if someone shared a workaround if they found it... It's odd because the git blame on that line seems to say it's been untouched for 3 years yet it seems like most typescript users would run into this if it was indeed broken 🤷

Edit: ended up sidestepping it with:

color: (context, props) => (props as any).color,

might be helpful to any other typescript noobs like myself out there 😜

@mdtusz
Copy link
Contributor

mdtusz commented Jun 16, 2021

Another way to get around this is by defining a props type/interface for the draw call and doing:

regl.prop<FooProps, "bar">("bar")

but it's not the nicest and requires the duplication of the key "bar" (or whatever you you are using).

@maritaria
Copy link

maritaria commented Nov 3, 2021

Looking at the type definition of DrawConfig<...> the Props type is third in the list, after Uniforms and Attributes.
What is nice about the type definition is that Uniforms and Attributes can be inferred when passing a literal config to the regl function (as in the README.md triangle sample).
The one you would need to set is Props, which cannot be inferred from the interface content when typing it as a literal.

I tried to build a wrapper function that would let you specify props, but that will break type inference as it only occurs when no type arguments are given.

Might I suggest abusing the profile field:

type TriangleProps = {
  speed: number;
  scale: number;
  width: number;
  height: number;
};

regl({
  profile: (context, props: TriangleProps, batch) => false,
  uniforms: {
    angle: function (context, props, batchId) {
      return props.speed * context.tick + 0.01 * batchId;
    },
  },
});

Or creating a regl factory function, this will be a function that wraps regl just to specify the props on the function itself.

import createREGL, {
  DefaultContext,
  DrawCommand,
  DrawConfig,
} from "regl";

const regl = createREGL();

function ragl<Props extends {}>(): <
  Uniforms extends {} = {},
  Attributes extends {} = {},
  OwnContext extends {} = {},
  ParentContext extends DefaultContext = DefaultContext
>(
  arg: DrawConfig<Uniforms, Attributes, Props, OwnContext, ParentContext>
) => DrawCommand<ParentContext & OwnContext, Props> {
  return regl;
}

type TriangleProps = {
  speed: number;
  scale: number;
  width: number;
  height: number;
};

ragl<TriangleProps>({
  uniforms: {
    angle: function (context, props, batchId) {
      return props.speed * context.tick + 0.01 * batchId;
    },
  },
});

Which is great except you then have the same problem with context.

@maritaria
Copy link

Another way to get around this is by defining a props type/interface for the draw call and doing:

regl.prop<FooProps, "bar">("bar")

but it's not the nicest and requires the duplication of the key "bar" (or whatever you you are using).

What would be nice for regl to do here is to default the 2nd type parameter to typeof Props so the first "bar" becomes optional.

@bergwerf
Copy link

bergwerf commented Nov 8, 2022

I think a more orthogonal solution would be to specify the Props in a props field (just like the uniforms field) instead of letting it be any extra field added to the input object.

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

5 participants