Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ threeDNumberArray[2][1] = 10; // 🚨 error: Type 'number' is not assign
threeDNumberArray[2][1][2][0] = 10; // 🚨 error: Property '0' does not exist on type 'Number'
```

Please be aware thatwhen using this function with a primitive instead of a literal type, such as when creating matrices of dynamic size—the exact return type can't be determined and will instead resolve to `any[]`.
Please be aware that when using this function with a primitive instead of a literal typesuch as when creating matrices of dynamic size—the exact return type cannot be determined and will instead resolve to `unknown[]`. This ensures an array of at least one dimension is returned, but is unable to provide any more safety than that. You must type the resulting matrix yourself, if you are able to provide more information than the compiler can infer. If not, then an explicit return type of `any[]` will provide the most 'relaxed' typing experience.

```ts
const createDynamicMatrix = (dimensions: number[]) => makeMatrix(dimensions, 0); // return type of any[]
const createDynamicMatrix = (dimensions: number[]) => makeMatrix(dimensions, 0); // return type of unknown[]
```

## Example
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ describe("assert types", () => {
expectType<string[][][][]>(makeMatrix([1, 1, 1, 1], "hello"));
expectType<number[][]>(makeMatrix([4, 5], ([a]) => a));
expectType<string[]>(makeMatrix([4], v => v[0].toString()));
expectType<any[]>(makeMatrix([] as number[])); // eslint-disable-line @typescript-eslint/no-explicit-any
expectType<unknown[]>(makeMatrix([] as number[]));

expectType<(0 | 1)[]>(
makeMatrix([1], () => (Math.random() > 0.5 ? (0 as const) : (1 as const)))
Expand Down
7 changes: 3 additions & 4 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,15 @@ export type Matrix<D extends number, T = unknown> = Brand<_Matrix<D, T, []>>;
* @remarks
* When a `_Matrix` is created without knowing it's exact size or number of dimensions, such
* as when creating one dynamically, it's impossible recursively construct a type for it.
* Instead, we short circuit the type to resolve to `any[]`, to avoid the typescript compiler
* throwing a `type instantiation is excessively deep...` error. This ensures an array of at
* least one dimension is returned, but unfortunately can't provide more safety than that.
* Instead, we short circuit the type to resolve to `unknown[]`. This ensures an array of at
* least one dimension is returned, but is unable to provide any more safety than that.
*/
type _Matrix<
D extends number,
T = unknown,
RecursionCountArray extends number[] = [],
> = number extends D
? any[] // eslint-disable-line @typescript-eslint/no-explicit-any
? unknown[]
: D extends RecursionCountArray["length"]
? T
: _Matrix<D, T[], [...RecursionCountArray, D]>;
Expand Down