🔎 Search Terms
equality, narrow, unknown, dynamic type checking
🕗 Version & Regression Information
- This changed between versions ______ and _______
- This changed in commit or PR _______
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about _________
- I was unable to test this on prior versions because _______
⏯ Playground Link
https://www.typescriptlang.org/play/?#code/GYVwdgxgLglg9mABBAhgZygUTCAtgRgB4AVRAUwA8oywATNRDAJxjAHMA+ACgDcUAbEGQBcicAGswcAO5gANIj78YtAGoChaUcQDaAXQCU2xAG8AUIkTA4TRFwgIMigSvWCyiOMGfK1GsmgGphaWiDDevP6IALyxPq7+QeahoUxkUCBMSEpCANwhlgC+IcWWUAAWTDKIYGTSiJhMVUxcBvnFZqCQsAjI6Fg4uABMJORUNPSMUCzs3DkiYmCSMvLxfu5aiLqGxslWNnYOYE5KCe6e3qfrmkkFYRHzMXFXbkK3KZZpGVlrr2T5KVKiCBFSq9Vq9UazVa7TMQA
💻 Code
import {describe, test} from "vitest";
import {assertEquals, assertThrows} from './vitest';
test('Return first value', () => {
assertEquals('first', castEnum('first', ['first']));
});
test('Return second value', () => {
assertEquals('second', castEnum('second', ['first', 'second']));
});
test('Throws for empty enum values', () => {
assertThrows(() => castEnum('value', []), '');
});
describe('Throws for an invalid enum value', () => {
test('Single valid value', () => {
assertThrows(() => castEnum('incorrect', ['correct']), '');
});
test('Multiple valid values', () => {
assertThrows(() => castEnum('incorrect', ['correct1', 'correct2']), '');
});
});
function castEnum<T extends string>(value: unknown, validValues: T[]): T {
if (validValues.length === 0) {
throw new Error();
}
for (const validValue of validValues) {
if (value === validValue) {
return value; // This throws error, but if you return validValue it passes
}
}
throw new Error();
}
🙁 Actual behavior
What I don't understand, if we're already inside if (value === validValue) that means both values value and validValue are the same, so return either value or validValue should pass, and match T.
But actual behaviour is that if you return validValue it works, but returning value, you get an typescript error:
TS2322: Type unknown is not assignable to type T
T could be instantiated with an arbitrary type which could be unrelated to unknown
🙂 Expected behavior
Returning both values should pass, because we've already checked that they're equal with value === validValue.
Additional information about the issue
No response
🔎 Search Terms
equality, narrow, unknown, dynamic type checking
🕗 Version & Regression Information
⏯ Playground Link
https://www.typescriptlang.org/play/?#code/GYVwdgxgLglg9mABBAhgZygUTCAtgRgB4AVRAUwA8oywATNRDAJxjAHMA+ACgDcUAbEGQBcicAGswcAO5gANIj78YtAGoChaUcQDaAXQCU2xAG8AUIkTA4TRFwgIMigSvWCyiOMGfK1GsmgGphaWiDDevP6IALyxPq7+QeahoUxkUCBMSEpCANwhlgC+IcWWUAAWTDKIYGTSiJhMVUxcBvnFZqCQsAjI6Fg4uABMJORUNPSMUCzs3DkiYmCSMvLxfu5aiLqGxslWNnYOYE5KCe6e3qfrmkkFYRHzMXFXbkK3KZZpGVlrr2T5KVKiCBFSq9Vq9UazVa7TMQA
💻 Code
🙁 Actual behavior
What I don't understand, if we're already inside
if (value === validValue)that means both valuesvalueandvalidValueare the same, so return eithervalueorvalidValueshould pass, and matchT.But actual behaviour is that if you return
validValueit works, but returningvalue, you get an typescript error:🙂 Expected behavior
Returning both values should pass, because we've already checked that they're equal with
value === validValue.Additional information about the issue
No response