Created
March 21, 2026 09:36
-
-
Save IlyaSemenov/dca88f2d427580fbdf04431b2d09084a to your computer and use it in GitHub Desktop.
Benchmark unknown[][] vs type alias
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import * as fs from 'fs'; | |
| import * as os from 'os'; | |
| import * as path from 'path'; | |
| import { execSync } from 'child_process'; | |
| const N = 500; | |
| const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'ts-alias-bench-')); | |
| // Generate version with inline unknown[][] | |
| let withInline = `\n`; | |
| for (let i = 0; i < N; i++) { | |
| withInline += ` | |
| interface Table${i} { | |
| values: unknown[][]; | |
| extra: unknown[][]; | |
| nested: { data: unknown[][] }; | |
| } | |
| function process${i}(t: Table${i}): unknown[][] { | |
| const v: unknown[][] = t.values; | |
| const e: unknown[][] = t.extra; | |
| const n: unknown[][] = t.nested.data; | |
| const combined: unknown[][] = [...v, ...e, ...n]; | |
| return combined; | |
| } | |
| `; | |
| } | |
| // Generate version with type alias (identical code, just aliased) | |
| const withAlias = | |
| `export type ValuesRows = unknown[][];\n` + | |
| withInline.replace(/unknown\[\]\[\]/g, 'ValuesRows'); | |
| const inlineFile = path.join(tmpDir, 'with-inline.ts'); | |
| const aliasFile = path.join(tmpDir, 'with-alias.ts'); | |
| fs.writeFileSync(inlineFile, withInline); | |
| fs.writeFileSync(aliasFile, withAlias); | |
| function runTsc(filePath: string): string { | |
| try { | |
| return execSync( | |
| `npx tsc --strict --noEmit --extendedDiagnostics "${filePath}"`, | |
| { encoding: 'utf-8', timeout: 30000 }, | |
| ); | |
| } catch (e: any) { | |
| console.error(`ERROR: ${path.basename(filePath)} has type errors:\n${e.stdout || e.stderr}`); | |
| process.exit(1); | |
| } | |
| } | |
| function extract(output: string, key: string): string { | |
| const match = output.match(new RegExp(`${key}:\\s+(.+)`)); | |
| return match ? match[1].trim() : 'N/A'; | |
| } | |
| const inlineOutput = runTsc(inlineFile); | |
| const aliasOutput = runTsc(aliasFile); | |
| const keys = [ | |
| 'Types', | |
| 'Instantiations', | |
| 'Symbols', | |
| 'Assignability cache size', | |
| 'Check time', | |
| 'Total time', | |
| 'Memory used', | |
| ]; | |
| console.log(`${N} interfaces, 5 usages of unknown[][] each\n`); | |
| console.log('Metric'.padEnd(28) + 'unknown[][]'.padEnd(14) + 'type alias'); | |
| console.log('-'.repeat(55)); | |
| for (const key of keys) { | |
| const v1 = extract(inlineOutput, key); | |
| const v2 = extract(aliasOutput, key); | |
| console.log(key.padEnd(28) + v1.padEnd(14) + v2); | |
| } | |
| fs.rmSync(tmpDir, { recursive: true }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment