0

I have made an interface for Velocityjs so I can use it in TypeScript, but I'm not sure how to correctly make interfaces for array types. This is a function for making calls[] for the Velocity.RegisterEffect method from the Velocity UI Pack:

let calls: [{ [key: string]: any }, number, { easing?: string, delay?: number }][] = keyFramesProps.map((p: string): [{ [key: string]: any }, number, { easing?: string, delay?: number }] => {
    let anim: KeyFrameSlitted = keyFramesSlitted[p];
    let durationPercentage = (+p.replace('%', '')) * 0.01;
    return [anim.props, durationPercentage, anim.options];
});

So I want to make an interface for the type: [{ [key: string]: any }, number, { easing?: string, delay?: number }]

This was the only thing that worked:

interface VelocityCall extends Array<any>{
    [0]: { [key: string]: any };
    [1]: number;
    [2]: { easing?: string, delay?: number };
}

I needed to extend Array, if not the compiler complained about missing methods on the array.

Now I can do this:

let calls: VelocityCall[] = keyFramesProps.map((p: string): VelocityCall => {
        let anim: KeyFrameSlitted = keyFramesSlitted[p];
        let durationPercentage = (+p.replace('%', '')) * 0.01;
        return [anim.props, durationPercentage, anim.options];
    });

Here is the rest of the Velocity interface (without the VelocityCall) if someone else need it or have a better solution:

interface VelocityOptions extends Object {

    queue?: string;
    duration?: number | "slow" | "normal" | "fast";
    easing?: string;
    begin?: any;
    complete?: any;
    progress?: any;
    display?: undefined | string;
    visibility?: undefined | string;
    loop?: boolean;
    delay?: number | boolean;
    mobileHA?: boolean;
    /* Advanced: Set to false to prevent property values from being cached between consecutive Velocity-initiated chain calls. */
    _cacheValues?: boolean;
    [key: string]: any;

}

interface Velocity {
    (element: Element, propertiesMap: "fadeIn" | "fadeOut" | "slideUp" | "slideDown" | "scroll" | "reverse" | "finish" | "finishAll" | "stop" | { [key: string]: any }, options?: VelocityOptions): Promise<Response>;
    RegisterEffect(name: string, effect: {
        defaultDuration?: number;
        calls: [{ [key: string]: any }, number, { easing?: string, delay?: number }][] | [{ [key: string]: any }, number][] | [{ [key: string]: any }][];
        reset: { [key: string]: any }
    });
}

declare var Velocity: Velocity;
4
  • It should be [{ [key: string]: any }, number, { easing?: string, delay?: number }] without the extra [] at the end, based on the VelocityCall interface you posted Commented Dec 1, 2016 at 11:14
  • Sorry, I removed the []. That was an array of VelocityCalls (copy past mistake) Commented Dec 1, 2016 at 11:18
  • And what errors do you get when you use this form? When I do this: let a: [{ [key: string]: any }, number, { easing?: string, delay?: number }]; I get all of the array methods for variable a. Commented Dec 1, 2016 at 11:26
  • I was asking about the correct way of making an interface for that type, and if there was a better way than extending Array<any>. Try to use the VelocityCall interface without the extends Array<any>. Commented Dec 1, 2016 at 11:29

1 Answer 1

3

What you're describing matches the tuple type as you want to describe an array of a specific length with specific types per index.

Instead of using an interface you can (and probably should) use:

type VelocityCall = [{ [key: string]: any }, number, { easing?: string, delay?: number }];
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.