A
arktype•3w ago
jack

type narrow issue on result

i have this really basic function
function validateTokens(
tokens: Partial<Tokens> | undefined
): Result<typeof Tokens.infer, ArkErrors> {
const validated = Tokens(tokens);

if (validated instanceof ArkErrors) { // also tried type.errors
return err(validated);
}

return ok(validated);
}
function validateTokens(
tokens: Partial<Tokens> | undefined
): Result<typeof Tokens.infer, ArkErrors> {
const validated = Tokens(tokens);

if (validated instanceof ArkErrors) { // also tried type.errors
return err(validated);
}

return ok(validated);
}
as far as I know, before upgrading the package, this worked fine more or less however, now there's simply no type narrowing. validated shows the same type inside of the if check, as well as after it am i doing something clearly wrong here?
15 Replies
jack
jackOP•3w ago
the type it shows is basically the union of the success and error types
ssalbdivad
ssalbdivad•3w ago
Can you add the full repro context?
jack
jackOP•3w ago
this repros
const AccessToken = type.string;
type AccessToken = typeof AccessToken.infer;
const RefreshToken = type.string;
type RefreshToken = typeof RefreshToken.infer;

export const Tokens = type({
access: AccessToken,
refresh: RefreshToken,
});
export type Tokens = typeof Tokens.infer;

function test( tokens: Partial<Tokens>) {
const test = Tokens(tokens);

if (test instanceof type.errors) {
return err(test.summary);
}

return ok(test);
}
const AccessToken = type.string;
type AccessToken = typeof AccessToken.infer;
const RefreshToken = type.string;
type RefreshToken = typeof RefreshToken.infer;

export const Tokens = type({
access: AccessToken,
refresh: RefreshToken,
});
export type Tokens = typeof Tokens.infer;

function test( tokens: Partial<Tokens>) {
const test = Tokens(tokens);

if (test instanceof type.errors) {
return err(test.summary);
}

return ok(test);
}
arktype 2.1.16
ssalbdivad
ssalbdivad•3w ago
This narrows for me
jack
jackOP•3w ago
interesting
ssalbdivad
ssalbdivad•3w ago
Maybe something to do with your tsconfig somehow? Not sure but it's definitely not a general issue
jack
jackOP•3w ago
ok 🤔 will dig into this
ssalbdivad
ssalbdivad•3w ago
I would add something that makes it a type error that it's not narrowed (maybe it already is for you) and see if that error also exists when you run tsc from the cli
jack
jackOP•3w ago
just rolled back the version and it's still here. no idea when i introduced this since i thought that tsc has been completing no problem, but i guess not does anything look wrong here? if not i'll figure this out tomorrow, just wanna make sure nothing is immediately broken
{
"include": ["**/*.ts", "**/*.tsx", "**/*.mjs"],
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Bundler",
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"isolatedModules": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"target": "ES2022",
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"noEmit": true
}
}
{
"include": ["**/*.ts", "**/*.tsx", "**/*.mjs"],
"compilerOptions": {
"strict": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Bundler",
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"isolatedModules": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"target": "ES2022",
"allowJs": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
},
"noEmit": true
}
}
ssalbdivad
ssalbdivad•3w ago
hmm, nothing jumps out 🤷
jack
jackOP•3w ago
ok, thank you. this is a tomorow issue then seems like mismatched versions in my monorepo caused this updating deps at 1am was a horrible idea
ssalbdivad
ssalbdivad•3w ago
Ahh makes sense, I should have thought of that Because of instanceof A lot of the time I try to avoid those issues by e.g. using string literal constants instead of symbols, but good reminder instanceof will still fail if there are multiple resolutions
jack
jackOP•3w ago
why does the string literal avoid this? also while i'm here- is there a substantial difference btwn checking if the result is instanceof type.errors vs ArkErrors?
ssalbdivad
ssalbdivad•3w ago
There are other similar cases where a string literal instead of a symbol would help, not this one (although you could do something like "byPath" in test and it would work for both versions because it doesn't reference where the class is declared) Generally best for many reasons though to make sure you have your versions aligned type.errors is just a reference to ArkErrors they're identical Honestly it's one of the better ways to find out you have mismatched versions I guess. Other things that can happen could be messier to debug hah
jack
jackOP•3w ago
true true. thanks for the help!

Did you find this page helpful?