Reputation: 89
Is it possible to specify the length of a double array upon parameter settings? for example:
class Matrix4x4{
constructor(matrix: /*must be a 4x4 number matrix*/){
}
}
Upvotes: 0
Views: 46
Reputation: 8383
If you don't need to limit the length of the array, and only need to define the array's elements you can use tuples like in David D.'s answer. However, in your case that would be the same as doing number[][]
.
Otherwise it gets a little tricky.
interface Array4<T> {
0: T;
1: T;
2: T;
3: T;
// Copied directly from the 'lib.d.ts' file
push(...items: T[]): number;
}
interface MatrixArray4x4<T> {
0: T;
1: T;
2: T;
3: T;
// Copied directly from the 'lib.d.ts' file
map<U>(callbackfn: (value: T, index: number, array: T[]) => U, thisArg?: any): U[];
}
// Alias for clarity
type MatrixData4x4 = MatrixArray4x4<Array4<number>>;
class Matrix4x4{
constructor(matrix: MatrixData4x4){
}
}
Works
var matrix: MatrixData4x4 = [
[1, 3, 3, 7],
[1, 9, 8, 4],
[9, 0, 0, 1],
[2, 0, 3, 8],
];
The type of a
is number
.
var a = matrix[0][0];
The type of b
is any
. If --noImplicitAny
is set, a type error will occur.
var b = matrix[4][0];
Works
new Matrix4x4([
[1, 3, 3, 7],
[1, 9, 8, 4],
[9, 0, 0, 1],
[2, 0, 3, 8],
]);
Error: Property 4
is not assignable in MatrixData4x4
.
new Matrix4x4([
[1, 3, 3, 7],
[1, 9, 8, 4],
[9, 0, 0, 1],
[2, 0, 3, 8],
[1, 2, 3, 4],
]);
Error: Property map
missing in the literal object.
new Matrix4x4({
0: [1, 3, 3, 7],
1: [1, 9, 8, 4],
2: [9, 0, 0, 1],
3: [2, 0, 3, 8],
});
Error: Property 3
missing in MatrixData4x4
.
new Matrix4x4([
[1, 3, 3, 7],
[1, 9, 8, 4],
[9, 0, 0, 1],
]);
Error: Property 3
missing in Array4<number>
.
new Matrix4x4([
[1, 3, 3],
[1, 9, 8, 4],
[9, 0, 0, 1],
[9, 0, 0, 1],
]);
Error: Type string
is not assignable to number
.
new Matrix4x4([
[1, '3', 3, 5],
[1, 9, 8, 4],
[9, '0', 0, 1],
[9, 0, 0, '1'],
]);
The limitation is that MatrixArray4x4
and Array4
don't extend Array
. So type errors will occur if Array
methods are called on it and they're not defined.
Works, since map
is defined above in MatrixArray4x4
.
matrix.map((x) => x[3]);
Works, since push
is defined above in Array4
.
matrix.map((arr) => arr.push(4));
Error: Property push
doesn't exist on the type MatrixArray4x4
.
matrix.push([1, 2, 3, 4]);
Error: Property map
doesn't exist on the type Array4
.
matrix.map((arr) => {
arr.map((x) => x[3]);
});
They way I got around this was to make an interface called ArrayMethods
containing all the methods from the Array
class without the element definition. I then extended that interface to make new limited length array interfaces.
Upvotes: 1
Reputation: 1419
Yes it's possible using Tuples. (see : https://github.com/Microsoft/TypeScript/blob/master/doc/spec.md#3.3.3 )
something like...
type TMatrixRow4x4 = [number, number, number, number];
type TMatrix4x4 = [TMatrixRow4x4, TMatrixRow4x4, TMatrixRow4x4, TMatrixRow4x4];
class Matrix4x4{
constructor(matrix: TMatrix4x4){}
}
You can change it around for any size matrix you might need.
Upvotes: 1