-
Notifications
You must be signed in to change notification settings - Fork 12.8k
never
-typed properties are required when instantiating object
#54053
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
Comments
This is working as intended, see #37104. And technically, a property typed |
Yes I see where you're coming from - but I suppose my objection is that instantiation is, by definition, not access. Or am I mistaken there? |
interface A {
a: string;
b: never;
} This type says it has two properties: one typed const a: A = {
a: "abc",
get b(): never { throw new Error(); }
}; A property typed |
Is this ever a thing? I can't repro this anyhow or I'm unsure what kind of access you have in mind: interface A {
a: string;
b: never;
}
declare const foo: A
foo.b // ok
const str: string = foo.b // fine, never is assignable to everything |
That’s the point - |
This doesn't really hold up as an objective truth, though. Plus, I think we're conflating thrown (runtime) errors and compile-time (type) errors, which are not the same thing. const Button = ({
_type,
href,
onClick,
}:
| { _type: "button"; onClick: () => void; href: never }
| { _type: "link"; onClick: never; href: string }) => {
console.log(href);
}; The destructuring assignment operation is "access" - is it not? This code does not result in a thrown error, nor a raised type error. I stand by my statement at the end of my original post - the utility of |
If you’re trying to ensure |
Be aware that the solution by @fatcerberus does not guarantee mutually exclusive types either. It's always a possibility that both properties are defined. And I essentially just repeated what Ryan said before:
|
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
1 similar comment
This issue has been marked 'Working as Intended' and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
Uh oh!
There was an error while loading. Please reload this page.
Bug Report
🔎 Search Terms
never, discriminated union
🕗 Version & Regression Information
I am seeing this bug in Typescript 5.0.4 (and in the latest beta at time of writing 5.1.0 Beta, and in the Nightly
v5.1.0-dev20230428
), but I do not know when it was introduced. I've also checked all 4.X releases in the Typescript Playground and it is indeed reproducible in all of them.This is the behavior in every version I tried, and I reviewed the FAQ for entries about
never
.⏯ Playground Link
Playground link with relevant code
💻 Code
🙁 Actual behavior
When instantiating
me
, the following type-error is produced:🙂 Expected behavior
I would expect that
never
-typed properties should not be "required" properties.Additional Context
The Playground link offers a minimal-reproducible case, but does not contextualise a real-world use-case. Of course I could just remove the
tailLength
property from thePerson
-type, and that would unblock me from instantiatingme
without atailLength
property. My real-world use case involves discriminated union patterns. I've been trying to build thisButton
component, which can render either an<a />
or<button />
element, depending on thetype
property that I pass to it. Here's what I tried originally:However, this produces type errors on
href
andonClick
, such as:I can address these errors by making all props present on both sides of the type-union, using
never
:And this resolves the errors in the component definition, raises type errors at the call-location:
Produces:
So, there is a circular issue here. In my opinion, making
never
-typed properties "required" basically reduces their utility, because (unless I'm mistaken) there is no valid value which you can pass (not evenany
!).The text was updated successfully, but these errors were encountered: