A
arktypeโ€ข16mo ago
OnkelTem

The inferred type of '... cannot be named without a reference to '../../../../node_modules/arktype/

I receive this strange message:
src/clients/client-amazon.ts:76:3 - error TS2742: The inferred type of 'get' cannot be named without a reference to '../../../../node_modules/arktype/dist/types/scopes/type'. This is likely not portable. A type annotation is necessary.
src/clients/client-amazon.ts:76:3 - error TS2742: The inferred type of 'get' cannot be named without a reference to '../../../../node_modules/arktype/dist/types/scopes/type'. This is likely not portable. A type annotation is necessary.
What's weird is that I don't see it in VSCode when editing code, but only when attepmting to build the project. Here is the code it's referrencing:
get<K extends keyof Config>(name: K) {
return config$$[name].assert(this.#config[name]);
}
get<K extends keyof Config>(name: K) {
return config$$[name].assert(this.#config[name]);
}
Here config$$ is a scope. How to properly type it?
38 Replies
OnkelTem
OnkelTemOPโ€ข16mo ago
Here is a working example:
OnkelTem
OnkelTemOPโ€ข16mo ago
import { type, scope, Type, Infer } from 'arktype';

// Helper to make Partial<T>
function partial<T extends object>(base: Type<T>) {
return type(
Object.fromEntries(
Object.entries(base.definition as object).map(([k, v]) => [`${k}?`, v]),
) as Infer<Partial<T>>,
);
}

const config$$ = scope({
foo: 'string',
bar: 'number',
}).compile();

const config$ = partial(type(config$$));

type Config = typeof config$.infer;

class Test {
#config: Config;
constructor(config: Config) {
this.#config = config$.assert(config);
}

// TODO: Add a type annotation of the return value
get<K extends keyof Config>(name: K) {
return config$$[name].assert(this.#config[name]);
}

get foo() {
return this.get('foo');
}
}
import { type, scope, Type, Infer } from 'arktype';

// Helper to make Partial<T>
function partial<T extends object>(base: Type<T>) {
return type(
Object.fromEntries(
Object.entries(base.definition as object).map(([k, v]) => [`${k}?`, v]),
) as Infer<Partial<T>>,
);
}

const config$$ = scope({
foo: 'string',
bar: 'number',
}).compile();

const config$ = partial(type(config$$));

type Config = typeof config$.infer;

class Test {
#config: Config;
constructor(config: Config) {
this.#config = config$.assert(config);
}

// TODO: Add a type annotation of the return value
get<K extends keyof Config>(name: K) {
return config$$[name].assert(this.#config[name]);
}

get foo() {
return this.get('foo');
}
}
ssalbdivad
ssalbdivadโ€ข16mo ago
This is a recurring issue with TS that in the past I've found to be related to symlinks from pnpm, but it often seems arbitrary when it occurs- was talking to @Vanilagy about this recently. Best thing to do is just annotate the type, there's usually a relatively non-painful way to extract out what you need and do it explicitly. Here's the TS issue: https://github.com/microsoft/TypeScript/issues/42873
GitHub
The inferred type of "X" cannot be named without a reference to "Y"...
Bug Report ๐Ÿ”Ž Search Terms inferred type cannot be named, symlink node_modules ๐Ÿ•— Version & Regression Information I'm verifying the problem on the [email protected]. I've not tried older ...
OnkelTem
OnkelTemOPโ€ข16mo ago
I see. Well, I'm not good at annotating ark-things yet ๐Ÿ™‚ yesterday I even created a thread about it, but it was too way wordy ๐Ÿ™‚
ssalbdivad
ssalbdivadโ€ข16mo ago
I did see that lol too much to catch up on taking the weekend off ๐Ÿ˜ฌ
OnkelTem
OnkelTemOPโ€ข16mo ago
sure, so I marked it "DELETE" hoping that some cleanup process can remove it
get<K extends keyof Config>(name: K) {
return config$$[name].assert(this.#config[name]);
}
get<K extends keyof Config>(name: K) {
return config$$[name].assert(this.#config[name]);
}
The return type shouldn't be Config[K] obviously, because I need to get this type from the scope Something like Space<{[K]: infer t}> ? Ah, I should use asOut probable, lmt Some rubbish:
type getSpaceArg<T> = T extends Space<infer P> ? P : never
// ...
get<K extends keyof Config>(name: K): asOut<getSpaceArg<typeof config$$>>[K] {
return config$$[name].assert(this.#config[name]);
}
type getSpaceArg<T> = T extends Space<infer P> ? P : never
// ...
get<K extends keyof Config>(name: K): asOut<getSpaceArg<typeof config$$>>[K] {
return config$$[name].assert(this.#config[name]);
}
And it doesn't even work for some reason Ideas? Nah, I give up
ssalbdivad
ssalbdivadโ€ข16mo ago
Sorry I wish I had more time to take a deeper look at this haha just trying to juggle a lot right now ๐Ÿคน
Unknown User
Unknown Userโ€ข16mo ago
Message Not Public
Sign In & Join Server To View
OnkelTem
OnkelTemOPโ€ข16mo ago
Just to make it clear. No need to read that topic. It must be deleted, and I would do it myself but I don't seem to have enough permissions What is relevant is this link:
ssalbdivad
ssalbdivadโ€ข16mo ago
Would it just be this:
get<K extends keyof Config>(name: K): Config[K] {
return config$$[name].assert(this.#config[name]) as never;
}
get<K extends keyof Config>(name: K): Config[K] {
return config$$[name].assert(this.#config[name]) as never;
}
OnkelTem
OnkelTemOPโ€ข16mo ago
Config[K] won't really work here because Config is Partial<typeof type(config$$)> And the idea of this "getter" is to get the type right from the scope So I wonder how that one can be fetched
ssalbdivad
ssalbdivadโ€ข16mo ago
I don't understand though That is the type of what assert would return
OnkelTem
OnkelTemOPโ€ข16mo ago
The return type of this function is
asOut<{
foo: string;
bar: number;
}[K]>
asOut<{
foo: string;
bar: number;
}[K]>
when it's inferred. I need to get the same but directly
ssalbdivad
ssalbdivadโ€ข16mo ago
Oh I see. I might change your names they're very confusing
const config$$ = scope({
foo: 'string',
bar: 'number',
}).compile();

const config$ = partial(type(config$$));
const config$$ = scope({
foo: 'string',
bar: 'number',
}).compile();

const config$ = partial(type(config$$));
Particularly that
OnkelTem
OnkelTemOPโ€ข16mo ago
haha, sorry, but I used double $$ for scope and single $ for type and thought it was a nice idea LOL
ssalbdivad
ssalbdivadโ€ข16mo ago
I mean you said you don't know what morphs are right? So you don't care about asOut
OnkelTem
OnkelTemOPโ€ข16mo ago
obviously it's not... yes, I don't know about morphs yet
ssalbdivad
ssalbdivadโ€ข16mo ago
So really all you need is Exclude<Config[K], undefined> or something
OnkelTem
OnkelTemOPโ€ข16mo ago
and the other way? is there another way?
ssalbdivad
ssalbdivadโ€ข16mo ago
I mean yeah you could try and use the /internal import syntax to get asOut but if you aren't using morphs it won't matter they will be equivalent
OnkelTem
OnkelTemOPโ€ข16mo ago
Well, let me clarify then. 1) first I define scope as a set of validators: const myScope = scope({ foo: 'string' }).compile() 2) then I convert it to a type const myType = type(myScope) 3) then I apply a function to it to get another type: const myType2 = f(myType) e.g. partial() Now, I need basically to get the type of an element from the myScope, as Scope[K], or Scope['foo'] - how to do this? So I don't think it's important if I use morphs or not, I just need to fetch the type from a scope by key I can do it this way I guess:
type getSpaceArg<T> = T extends Space<infer P> ? P : never

get<K extends keyof Config>(name: K): getSpaceArg<typeof config$$>[K] {
return config$$[name].assert(this.#config[name]) as never;
}
type getSpaceArg<T> = T extends Space<infer P> ? P : never

get<K extends keyof Config>(name: K): getSpaceArg<typeof config$$>[K] {
return config$$[name].assert(this.#config[name]) as never;
}
but it looks too cumbersome.
ssalbdivad
ssalbdivadโ€ข16mo ago
Sorry still lost on this one. Can you give an example where Exclude<Config[K], undefined> would not give the result you want?
OnkelTem
OnkelTemOPโ€ข16mo ago
It will work in this particular case. But it depends on the way how Config was made (parial applied). What if there was another tranformation of the original type?
ssalbdivad
ssalbdivadโ€ข16mo ago
I just think what you're doing is quite hard to follow but based on what you've written that is the correct type. If for some reason you need to extract the original type from the space I guess something like the conditional you wrote is your best bet. I will try and optimize some of these things for library authors to make them easier in the next release
OnkelTem
OnkelTemOPโ€ข16mo ago
Hm. Ok then. I just thought there was a way to simply take out something from the scope as easy as I do with type
ssalbdivad
ssalbdivadโ€ข16mo ago
You can with a scope, not with a space though Spaces are just collections of types, they don't have all the extra methods like .infer on them
OnkelTem
OnkelTemOPโ€ข16mo ago
Well, so... when I do this, I get space then?
const config$$ = scope({
foo: 'string',
bar: 'number',
}).compile();
const config$$ = scope({
foo: 'string',
bar: 'number',
}).compile();
compile() converts scope to a space?
Dimava
Dimavaโ€ข16mo ago
Yes
OnkelTem
OnkelTemOPโ€ข16mo ago
Ahhhh that's it I would really like to take part in making documentation but at my current level of familiarity with the library, I'm afraid I will be barely useful
Dimava
Dimavaโ€ข16mo ago
I'd say it's the opposite You have things to do and no idea how does the lib work
OnkelTem
OnkelTemOPโ€ข16mo ago
wdym sorry?
Dimava
Dimavaโ€ข16mo ago
Documentation ismade for people like you Not us who already know every drop
OnkelTem
OnkelTemOPโ€ข16mo ago
Sure. But I know a lot of cases when users were creating documentation and even writing books
Dimava
Dimavaโ€ข16mo ago
So if you collect all our answers as markdown that's half work done Then a bit of polish by you so you understand better and by us so it's more correct and ideomatic
ssalbdivad
ssalbdivadโ€ข16mo ago
I appreciate you wanting to help! Hopefully once I release some baseline docs with beta you can help augment them as you gain more familiarity with ArkType!
Dimava
Dimavaโ€ข16mo ago
@OnkelTem so while you are still new, ask 5-10 stupid questions you can imagine yourself asking for actual work (but don't know answer yet)

Did you find this page helpful?