Repository navigation
Add basic types <Byte> and <Integer>Β #62867
Description
π Search Terms
typescript integer type
typescript integer limit
typescript byte type
typescript Uint8Array type
β Viability Checklist
- This wouldn't be a breaking change in existing TypeScript/JavaScript code
- This wouldn't change the runtime behavior of existing JavaScript code
- This could be implemented without emitting different JS based on the types of the expressions
- This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
- This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
- This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals
β Suggestion
It would be nice to have basic types such as Byte or Uint8 that can match what is put into Uint8Array as default types
Currently using hacky wordaround to limit Byte type in typescript to 256 values.
type Byte = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255;
This might have been discussed already, and I found some stale issues where addition of integer type was explicitly excluded as design goal.
not sure if this is really related but it goes into same direction I think #62752
also the docs show one mention of Uint8Array and there is not even a data type definition in the docs. only thing I can find is: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-5-7.html which defines it as interface Uint8Array<TArrayBuffer extends ArrayBufferLike = ArrayBufferLike>.
Please nobody suggest to use single-item ArrayBuffer as a type for byte because people think in Integer and in Byte not in ArrayBuffer or Buffer.
π Motivating Example
right now let byte: number; could be float or anything. I don't use typescript to have floats where I expect bytes when working with things like Uint8Array
π» Use Cases
- Have an idiot proof, easy way to ensure that a value is a single byte
Activity
MartinJohns commentedon Dec 9, 2025
Duplicate of #195 / #4639.
bf commentedon Dec 9, 2025
Hi Martin, they were opened in 2014/2015 and both closed in 2018 - it's a long time ago.
Not sure what the "mission statement" of typescript is nowadays, but if it is supposed to be a tool which makes code more robust it would be clever to add basic integer validation.
jcalz commentedon Dec 9, 2025
#54925 is the currently-open issue that encompasses this.
bf commentedon Dec 9, 2025
Unfortunately #54925 is also stale.
Maybe this is some practical inside joke but how come that after all these years there is still no proper way to ensure a positive integer is provided to a function and have the static type checks. I don't want to hack my own types or do runtime validation for something that is supposed to catch compile-time typos.
I find guides such as https://www.convex.dev/typescript/typescript-101/basic-types-variables/typescript-integer-type where they seriously recommend to go the
parseInt(x, 10)route again. I've usedparseIntfor input validation a decade ago, now it's 2025 and it is not solved?Is this some sick "embrace extend extinguish" by Microsoft? Am I too stupid to see the obvious solution?
MartinJohns commentedon Dec 9, 2025
See: https://github.com/microsoft/typescript/wiki/faq#time-marches-on
mkantor commentedon Dec 9, 2025
Benjamin Flesch (@bf) if you want advice about a particular use case you could consider asking on the community Discord server, or maybe StackOverflow if the question seems like a good fit there.
bf commentedon Dec 9, 2025
Thanks for your kind replies. Will close this issue as I don't see any perspective how this will be fixed.
There is an internal
UINT8CLAMPEDtype in ECMAScript specs and it is also implemented in V8 engine. So it would be easy to add native support for it, saving 3 bytes for each number that is stored. See https://tc39.es/ecma262/multipage/indexed-collections.html#sec-uint8array and https://github.com/v8/v8/blob/5a615fbf808238714481b647676d65ba4ae62bbb/src/compiler/turboshaft/turbolev-graph-builder.cc#L5188There's even a recent ECMAscript proposal to add native
Decimaltype which also highlights current deficiencies of the language, see https://github.com/tc39/proposal-decimalUnfortunately the native Decimal proposal seems to have been shot down already, as discussed in tc39/proposal-decimal#192
My expectation coming to typescript was that this whole class of Integer problems was finally solved, and I was a shocked that it still is such a problem.
Seems like one has to fork v8 and deno to achieve this.
MartinJohns commentedon Dec 9, 2025
That... Really makes no sense. V8/Deno are runtimes, TypeScript is a compile-time only language. Even if such an integer type would have been added in TypeScript, it would have NO effect on the runtime code.
bf commentedon Dec 10, 2025
My workaround for things like
int8,uint8,int16anduint16in typescript is to explicitly define the type with numeric literals. Now I can useByteandByte[]types properly.It also works when passing an array directly to a function without explicitly specifying it as
Byte[].Use command line to generate literal types:
Workaround for
Bytetype in typescript:mkantor commentedon Dec 10, 2025
Benjamin Flesch (@bf) you can also get cute and infer out of template literal types to generate such unions:
But I think generally writing out the union is preferable. Even better than that is not leaning on giant unions in the first place (for multiple reasons, but a big one being they can significantly bog down type checking performance).
bf commentedon Dec 10, 2025
Thanks Matt Kantor (@mkantor), that's a clever approach. Unfortunately it does not work for 32 bit because - as expected -
Expression produces a union type that is too complex to represent.. Was generating a multi-gigabyteuint32type file already, but that approach obviously won't work...Yes, simply using the workaround with
Byte[]type to ensure that I don't get floats or negative numbers as function parameters is worth it. I persisted the types at https://github.com/bf/typescript-integer-types-uint8-int8-uint16-int16#Yes, finally someone who understands me - how about we add/expose proper integer types that are already there in V8/ECMAScript specs. But I understand that you won't move into that direction. π
How about this: TypeScript adds some sort of options for numeric parsing, so we don't need to abuse the expression parser. Why can't the expression parser have special case such as
number<positive>? Or support for '+' operator when parsing digits, so that[0-9]+works at least? This would be a typescript-only decision.Alternatively you should allow to define array lengths with the types, so that
const foo: Uint8ClampedArray[1]fails when the array is empty or has more than one byte. If I think about it, maybe the array length specification is best.mkantor commentedon Dec 10, 2025
I'm just a random TypeScript user, not a maintainer (though I've made some rather small contributions in this repository).
If you have other feature requests I think you ought to propose them in new issues. Be sure to search existing issues first though, like #41666, #43505, the related issues linked in comments above, etc.
You can already do this with tuple types, though I think that only works for
Arrays and not things likeUint8Array.I feel like you're probably already aware of
bigint, but since it hasn't been mentioned yet in this thread I thought I ought to gesture towards it.MartinJohns commentedon Dec 10, 2025
I get the workaround, also why you want this feature (I'd like it too). What confused me was the statement that you'd need to fork V8/Deno to achieve this, when the runtimes have nothing to do with the TypeScript types.
I'm not aware of any ECMAScript types beyond
NumberandBigInt.The issue that is being underestimated is the big can of worms that follows. Is an
integerassignable to anumber? Most would assume so. And an object with such a typed property? It introduces more unsoundness. You'd need to haveintegerbe a subset ofnumber, which is not something TypeScript currently has otherwise. Same deal withbyteand any others. It's not as trivial to properly implement and support as you might think (feel free to prove me wrong :-P).