Comments (11)
To clarify since this is a common point of confusion: { work: never }
doesn't mean an object that never has a work
property. It means an object that always has a work
property whose value is type never
. You can't legally create such an object at runtime since no such value exists.
from typescript.
It means an object that always has a
work
property whose value is typenever
. You can't legally create such an object at runtime since no such value exists.
Or a property that throws upon access. It's fine to create a throwing getter.
from typescript.
You still seem to mistakingly believe that having a never
typed property makes it an "impossible value", but that's not the case.
type T = { value: never }
const t: T = { get value(): never { throw new Error() } }
from typescript.
I think you missed the implicit cast due to the type annotation in the function header 😉
That's not a cast, it's just a normal return type annotation. If JSON.parse()
returned something other than any
(like unknown
), then the program would have had an error. The root of the issue in that particular example is that an unsound assignment to { work: never }
isn't caught because the assignment source is any
.
The bottom type means you can never access this value without throwing. As long as that invariant is maintained, then any assignment from never
to any other type is sound, which is why the type system allows it.
from typescript.
Just in case someone finds this helpful: Instead of mapping the not JSONable keys to never, now, I map the whole type to never like JSONSerializable = T extends JSONValue ? T : never. This prevents false assignments.
The ideal solution for this use case would be #23689, but I don't know if we'll ever get it
from typescript.
awesome, I learned something. I agree that it works as intended and #23689 is the feature I am looking for. Thanks a lot for taking the time!
from typescript.
never
is the bottom type and is intentionally assignable to all other types. This is because the type is an empty set and has no inhabitants - by definition you can never have a value of type never
. If the return type of getLaborer
were accurate, the function could never return normally since it's impossible to construct a LazyLaborer
.
from typescript.
Thanks for your fast replies :)
It means an object that always has a
work
property whose value is typenever
. You can't legally create such an object at runtime since no such value exists.
That is exactly my point. Yet, the example creates such a value of the impossible LazyLaborer
type and assigns it to a variable of the valid Laborer
type. There is no way, the example would not produce an (unintended) runtime exception. Therefore, I expect TypeScript to not compile.
I fail to see, that assigning an impossible type to a possible type can be a correct, type safe assignment. I feel like, I am missing something here?
The LazyLaborer
example is of course stupid. But the ability to write a function parse<T>(serializedValue: string): JSONSerializable<T>
and having a compile error when I try to generate a not possible type, would be quite valuable to me.
from typescript.
The problem with the example, and why it’s not an error as written, is because JSON.parse
returns any
. That’s a separate issue; the part where { work: never }
is assignable to { work: LiterallyAnythingElse }
is working as intended. Normally you wouldn’t be able to assign anything to LazyLaborer
without a compile error, but any
is the “shut up and leave me alone, TypeScript” type. 😄
from typescript.
I fail to see, that assigning an impossible type to a possible type can be a correct, type safe assignment.
It’s a bit weird, but the mathematical explanation is that it’s the same as how the empty set is a subset of all other sets. More prosaically, if you have a function of type () => never
, then that function by definition must always throw, so you can use it in place of () => T
for any T
. And since () => T
is isomorphic to T
…
from typescript.
Long story short: We can close this issue as works as intended, right?
Thanks a lot for your detailed answers! :)
Nevertheless, I think it would be useful, if assigning an impossible value to something would be a caught error by the compiler. I see no intentional use of writing a program, whose static types cannot reflect its runtime types. From my point of view, programming languages should be useful and help me to prevent errors: In the example me.work()
will lead to a runtime error, which could have been caught by the compiler. I mean, let i = 0; ... i = 1; ...
is mathematically questionable, yet surely useful in a for loop 😜
Do you think a feature request for that would be valid? If not, I will trust your judgement 👍
P.S.:
The problem with the example, and why it’s not an error as written, is because
JSON.parse
returnsany
. That’s a separate issue;
I think you missed the implicit cast due to the type annotation in the function header 😉
P.P.S:
Just in case someone finds this helpful: Instead of mapping the not JSONable keys to never
, now, I map the whole type to never
like JSONSerializable<T> = T extends JSONValue ? T : never
. This prevents false assignments.
from typescript.
Related Issues (20)
- Error when accessing CSS property value using kebab case in `CSSStyleDeclaration` object HOT 1
- Type 'never' incorrectly inferred for mixed primitive type properties assignment with strictNullChecks disabled HOT 2
- Array of object unions not working as expected HOT 2
- Support WebIDL interfaces nominally (not just structurally) HOT 9
- Improve type inference for nullish coalescing (??) after null checks on multiple variables HOT 2
- [NewErrors] 5.7.0-dev.20240915 vs 5.6.2 HOT 6
- [ServerErrors][JavaScript] 5.7.0-dev.20240915 vs 5.6.2 HOT 3
- [ServerErrors][TypeScript] 5.7.0-dev.20240915 vs 5.6.2 HOT 4
- Inlay parameter hints don't account for trailing required parameters HOT 1
- JsDoc with overloads and different generics results in wrong dts output
- Generic Conditional Type resolved to `any` when passed an error `any` type HOT 8
- Typescript v5.6.2 resulting in "Overload signatures must all be optional or required." on alpine linux arm64 HOT 2
- File watching is registering thousands of redundant watchers
- File watching creates hundreds of recursive watchers in mono-repo when opening loose file
- Raise tsconfig default to ES2015 or later HOT 1
- Computed type key inference inconsistent with identical explicitly declared type HOT 2
- Do we need to import twice to pick up global augmentations HOT 1
- Cannot access protected field but private field inside nested class
- No error for non-existing css side effect import with `noUncheckedSideEffectImports` flag on HOT 8
- CommonJS module output broken after updating from 5.5.4 to 5.6.2 HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from typescript.