Skip to content

Commit 6cdb8ec

Browse files
authored
fix: Improve return type specificity (#66)
2 parents f41dc82 + c7c9a41 commit 6cdb8ec

File tree

2 files changed

+47
-21
lines changed

2 files changed

+47
-21
lines changed

src/__tests__/index.test.ts

+10-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { inspect } from "node:util";
22
import { describe, test, expect } from "@jest/globals";
3-
import Matrix from "../index.js";
3+
import Matrix, { Matrix1D, Matrix2D } from "../index.js";
44

55
describe("Matrix", () => {
66
const error = new TypeError("Matrix must be a number or array of numbers");
@@ -18,11 +18,18 @@ describe("Matrix", () => {
1818
});
1919

2020
test("does not throw number array", () => {
21-
expect(Matrix.bind(Matrix, [1])).not.toThrowError(error);
21+
expect(
22+
Matrix.bind<typeof Matrix, [x: number[]], [], Matrix1D>(Matrix, [1])
23+
).not.toThrowError(error);
2224
});
2325

2426
test("does not throw 2D number array", () => {
25-
expect(Matrix.bind(Matrix, [[1], [2]])).not.toThrowError(error);
27+
expect(
28+
Matrix.bind<typeof Matrix, [x: number[][]], [], Matrix2D>(Matrix, [
29+
[1],
30+
[2],
31+
])
32+
).not.toThrowError(error);
2633
});
2734
});
2835

src/index.ts

+37-18
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,29 @@ interface IMatrix {
55
countRows: () => number;
66
countColumns: () => number;
77
addable: (y: Matrix) => boolean;
8-
add: (y: Matrix) => Matrix;
98
multipliable: (y: Matrix) => boolean;
109
multiply: (y: Matrix) => Matrix;
11-
transpose: () => Matrix;
12-
invert: () => Matrix;
10+
transpose: () => Matrix2D;
1311
map: (x: any) => Matrix;
1412
}
1513

16-
interface Matrix1D extends IMatrix {
14+
export interface Matrix1D extends IMatrix {
1715
__value: number[];
16+
add: (y: Matrix1D) => Matrix1D;
17+
invert: () => Matrix1D;
1818
valueOf: () => number[];
1919
}
2020

21-
interface Matrix2D extends IMatrix {
21+
export interface Matrix2D extends IMatrix {
2222
__value: number[][];
23+
add: (y: Matrix2D) => Matrix2D;
24+
invert: () => Matrix2D;
2325
valueOf: () => number[][];
2426
}
2527

2628
type Matrix = Matrix1D | Matrix2D;
2729

28-
function isMatrix1D(matrix: Matrix): matrix is Matrix1D {
30+
export function isMatrix1D(matrix: Matrix): matrix is Matrix1D {
2931
return matrix.countRows() === 1;
3032
}
3133

@@ -37,7 +39,9 @@ function isMatrix1D(matrix: Matrix): matrix is Matrix1D {
3739
* @throws {TypeError} Argument x must be a number or number array
3840
* @return {Matrix} Single or multi dimensional matrix
3941
*/
40-
function Matrix(x: number[] | number[][]): Matrix {
42+
function Matrix(x: number[]): Matrix1D;
43+
function Matrix(x: number[][]): Matrix2D;
44+
function Matrix<T extends number[] | number[][]>(x: T): Matrix1D | Matrix2D {
4145
// extra nesting
4246
if (Array.isArray(x[0]) && x.length === 1) {
4347
throw new TypeError("Matrix must be a number or array of numbers");
@@ -79,14 +83,17 @@ Matrix.addable = function (x: Matrix, y: Matrix): boolean {
7983
* @throws {TypeError} Matrices are not addable
8084
* @return {Matrix} New matrix with the summation
8185
*/
82-
Matrix.add = function (x: Matrix, y: Matrix): Matrix {
86+
function Add(x: Matrix1D, y: Matrix1D): Matrix1D;
87+
function Add(x: Matrix2D, y: Matrix2D): Matrix2D;
88+
function Add<T extends Matrix1D & Matrix2D>(x: T, y: T): Matrix1D | Matrix2D {
8389
if (!Matrix.addable(x, y)) throw new TypeError("Matrices are not addable");
8490
return x.map((row: number[], i: number): number[] =>
8591
row.map((column: number, j: number): number => {
8692
return column + (Array.isArray(y.__value[i]) ? y.__value[i][j] : 0);
8793
})
8894
);
89-
};
95+
}
96+
Matrix.add = Add;
9097

9198
/**
9299
* Determines whether two matrices can be multiplied
@@ -150,14 +157,17 @@ Matrix.multiply = function (x: Matrix, y: Matrix): Matrix {
150157
};
151158

152159
/**
153-
* Inverts a matrix
160+
* Inverts a matrix. Matrix must be a square (e.g. 1x1 or 2x2)
154161
* @alias module:matrix.invert
155162
* @param {x} Matrix to invert
156163
* @return {Matrix} Matrix inverse
157164
*/
158-
Matrix.invert = function (x: Matrix): Matrix {
159-
return Matrix(inv<any>(x instanceof Matrix ? x.__value : x));
160-
};
165+
function Invert(x: Matrix1D): Matrix1D;
166+
function Invert(x: Matrix2D): Matrix2D;
167+
function Invert<T extends Matrix1D & Matrix2D>(x: T): Matrix1D | Matrix2D {
168+
return Matrix(inv<any>(x.__value));
169+
}
170+
Matrix.invert = Invert;
161171

162172
/**
163173
* Counts rows in this matrix
@@ -195,9 +205,15 @@ Matrix.prototype.addable = function (this: Matrix, y: Matrix): boolean {
195205
* @param {Matrix} y - Matrix to add
196206
* @return {Matrix} New matrix with the summation
197207
*/
198-
Matrix.prototype.add = function (this: Matrix, y: Matrix): Matrix {
208+
function add(this: Matrix1D, y: Matrix1D): Matrix1D;
209+
function add(this: Matrix2D, y: Matrix2D): Matrix2D;
210+
function add<T extends Matrix1D & Matrix2D>(
211+
this: T,
212+
y: T
213+
): Matrix1D | Matrix2D {
199214
return Matrix.add(this, y);
200-
};
215+
}
216+
Matrix.prototype.add = add;
201217

202218
/**
203219
* Determines whether this matrix can be multiplied
@@ -224,7 +240,7 @@ Matrix.prototype.multiply = function (this: Matrix, y: Matrix): Matrix {
224240
* @alias module:matrix#transpose
225241
* @return {Matrix} New matrix with the transpose
226242
*/
227-
Matrix.prototype.transpose = function (this: Matrix): Matrix {
243+
Matrix.prototype.transpose = function (this: Matrix): Matrix2D {
228244
if (isMatrix1D(this)) {
229245
return Matrix(unzip([this.__value]));
230246
} else {
@@ -237,9 +253,12 @@ Matrix.prototype.transpose = function (this: Matrix): Matrix {
237253
* @alias module:matrix#invert
238254
* @return {Matrix} Matrix inverse
239255
*/
240-
Matrix.prototype.invert = function (this: Matrix): Matrix {
256+
function invert(this: Matrix1D): Matrix1D;
257+
function invert(this: Matrix2D): Matrix2D;
258+
function invert<T extends Matrix1D & Matrix2D>(this: T): Matrix1D | Matrix2D {
241259
return Matrix.invert(this);
242-
};
260+
}
261+
Matrix.prototype.invert = invert;
243262

244263
/**
245264
* Maps over this matrix

0 commit comments

Comments
 (0)