Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't get named types when inferring types with JSDoc #3936

Open
andreasputlitz opened this issue Jan 7, 2025 · 0 comments
Open

Can't get named types when inferring types with JSDoc #3936

andreasputlitz opened this issue Jan 7, 2025 · 0 comments

Comments

@andreasputlitz
Copy link

andreasputlitz commented Jan 7, 2025

So, I have spend a lot of time on this now, digging around. I am trying to infer a type from a ZodSchema, and have it be a named type, so that I don't get the structure shown on hover, but the name of the type.

Following example, this is how I would expect it to work:

const DogZod = z.object({
	name: z.string(),
	age: z.number()
});

/**
 * @typedef {Object} DogOld
 * @prop {string} name
 * @prop {number} age
 */

/** @returns {DogOld} */

function return_dog(dog) {
	const result = DogZod.parse(dog);
	return result;
}

const doggy = { name: 'hunter', age: 5 };

const this_is_dog = return_dog(doggy);

Here, hovering over this_is_dog will show me the named type of OldDog:

const this_is_dog: DogOld

So far, so expected.

Now, if I try to infer the type from the Zod-schema, and try to name it, like this:

const DogZod = z.object({
	name: z.string(),
	age: z.number()
});

/**
 * @typedef {z.infer<typeof DogZod>} DogNew
 * */

/** @returns {DogNew} */

function return_dog(dog) {
	const result = DogZod.parse(dog);
	return result;
}

const doggy = { name: 'hunter', age: 5 };

const this_is_dog = return_dog(doggy);

Now, hovering over this_is_dog will only give me the anonymous type:

const this_is_dog: {
    name: string;
    age: number;
}

I am also using the TypeScript Explorer extension, and it also doesn't show the named type, so I don't think it is a quirk with the hover intellisense.

I have already tried to create a new type intersection with an empty object as recommended in a couple of places, but this didn't have the desired effect.

/**
 * @typedef {{} & DogZod} DogNew
 * @typedef {z.infer<typeof DogZod>} DogZod
 * */

What does work, is this however:

/**
 * @typedef {Record<any, any> & z.infer<typeof DogZod>} DogNew
 * */

Now I get DogNew as type on hover. But now of course the type definition of DogNew is useless, because now it will accept any another arbitrary number of extra attributes.

It seems to me, that z.infer<> somehow "breaks" the naming of the type with JSDoc, which can only be healed when intersected with another type, which can't be an empty object, which then again defeats the purpose of having the type in the first place.

Am I missing something here?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant