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)
- Incorrect type handing/reduction HOT 3
- [transpileDeclaration API][5.5] Self referencing generic type constraint with union gets emitted as `unknown`
- Syntax highlighting can not resolve @throws of tsdoc HOT 3
- tsc crash with `Error: start < 0` in a specific config HOT 1
- computeCommonSourceDirectory doesn't work with subst on windows
- Type union not matched starting from TS 5.1 HOT 3
- union with `any` shows as union in signature quickinfo but `any` in parameter quickinfo HOT 5
- Add strictFunctionTypes to Enhance Type Safety for Function Parameters HOT 3
- Methods of classes extended in others do not inherit the types of method arguments. HOT 4
- TypeScript colorizer confused by comments after colon in class member function signature with Generic return type HOT 1
- More flexible handling of circular types with "typeof function" inference HOT 4
- If statement return type with union inferred incorrectly HOT 5
- Compiler cannot handle promise.then(null | undefined) HOT 4
- Meta: Normative Changes for Explicit Resource Management
- Declaration emit does not remember the names it assigned to certain type parameters
- Nullish coalescing operator but for conditional types HOT 2
- Function generic unmatched: Matching hehavior is difference between arrow functions and normal function
- Method `concat` has wrong typization HOT 3
- Invalid type inference for optional chaining operator when nullish check is extracted to `const` varaiable HOT 2
- Inline type annotations for destructured properties using angle bracket syntax HOT 3
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.