Motion: [BUG] Typescript error when using useTransform to combine 2 useTransforms

Created on 6 Nov 2020  Â·  6Comments  Â·  Source: framer/motion

2. Describe the bug
I have 2 useTransforms (x, y) which I want to combine into a string to use as a CSS transform (not sure of what other way to do this — top/left isn't performant)
image

  const progress = useSpring(0, {spring});
  const x = useTransform(progress, [0, 1], [0, 100]);
  const y = useTransform(progress, [0, 1], [0, 100]);
  const t = useTransform([x, y], ([x:, y]) => `translate(${x}px, ${y}px)`);

But when I pass them into a 3rd useTransform to combine, typescript complains

TypeScript error in /Users/tarng/Code/playspace/src/av/Stream.tsx(21,26):
No overload matches this call.
  Overload 1 of 3, '(input: MotionValue<unknown>, transformer: SingleTransformer<unknown, unknown>): MotionValue<unknown>', gave the following error.
    Argument of type 'MotionValue<number>[]' is not assignable to parameter of type 'MotionValue<unknown>'.
      Type 'MotionValue<number>[]' is missing the following properties from type 'MotionValue<unknown>': current, prev, timeDelta, lastUpdated, and 19 more.  TS2769

    19 |   const x = useTransform(progress, [0, 1], [0, 100]);
    20 |   const y = useTransform(progress, [0, 1], [0, 100]);
  > 21 |   const t = useTransform([x, y], ([x, y]) => `translate(${x}px, ${y}px)`);
       |                          ^

if i try this on codepen without strict typescript, it throws this error:

image

3. IMPORTANT: Provide a CodeSandbox reproduction of the bug
https://codesandbox.io/s/framer-motion-2-animatesharedlayout-animate-between-different-components-forked-qmgro?file=/src/App.js

4. Steps to reproduce

Steps to reproduce the behavior:
Load the prototype, see typescript or type error

5. Expected behavior

It should run

6. Video or screenshots
N/A
7. Environment details
Chrome, macos

bug

All 6 comments

complains even with the sample code from the overload definition
image

Ive also run into this, not sure how to fix though. Currently I've worked around it with a as any with the properties

i cry

const x = useTransform([progress, mousePos.x] as MotionValue[], (([progress, start]: number[]) => lerp(start, targetX, progress)));
  const y = useTransform([progress, mousePos.y] as MotionValue[], (([progress, start]: number[]) => lerp(start, targetY, progress)));

@tarngerine yeah I just poked around a bit I think thats as good as your gonna get for now. I'll see if I can try to understand the TS in there well enough to fix it but I'm not sure

A type of parameter of useTransform is defined as input: MotionValue<string | number>[].
https://github.com/framer/motion/blob/dc571a6625dafa1d195d569db6b84c449fcc4140/src/value/use-transform.ts#L163
When strictFunctionTypes in tsconfig is set to true, MotionValue<number> is not assignable to MotionValue<string | number>.
This is because MotionValue has functions which have parameter of type string | number, and number => void is not assignable to (number|string) => void.
You can see the error in the link below and if you set strictFunctionTypes to false, the error will disappear.
https://www.typescriptlang.org/play?#code/PTAEFcDsEsHtNAFwJ4AcCmpUEMBO2BbdRdXAWACgAbYpAQVAF5QAKADwC5RJwCAjUgEomAPlABvAL4BuSjURIAQk1aduvAblAAfUAGdEuaJADmwxmKmyKiBs0SLrDlbelA

~Probably useTransform needs conditional types.~ I found conditional types is not needed.

The version of framer-motion in the above codesandbox is too old.

Minimal repro:
https://codesandbox.io/s/framer-motion-simple-animation-forked-8p25e?file=/src/index.tsx

Was this page helpful?
0 / 5 - 0 ratings