user3717718 user3717718 - 2 days ago 3
TypeScript Question

Interface for Array Types in TypeScript

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;

Answer

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 }];
Comments