-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Structural Subtyping with Control flow based type analysis #10065
Comments
Continuing to think about this but it'd be very expensive -- we'd be resynthesizing a type for |
migrated from #12919 allow an object narrowed to a certain interface be used where such interface is expected interface A { value: number | string };
interface B { value: number; }
function takeOnlyB(value: B): void {}
const data: A = { value: 'hey' };
data.value = 1; // <-- from this point on we know for sure that value is number
takeOnlyB(data); // <-- problem, despite effectively being of type `B` data still can't be used
// expected: takeOnlyB should accept data because it's been asserted to comply with `B`
|
duplicate of #8545 |
would also be an asnwer to mixins or partial classes |
A casual observation is that allowing this would be unsound because someone could hold a reference to the guarded object, then have the object mutate at a later point during execution to have an incorrectly-typed property (from the perspective of the callee). We're in general very unsound in this regard already so it's not really a reason to not do the feature... but people are always telling me TypeScript is Very Bad because it's unsound so I figured it was worth mentioning in the context of this suggestion 🙄 |
Unsound? Yes. In all seriousness, it works for people, lets us get our jobs done, and follows its stated goals. The rough edges, which are getting smoother every day, come more from things like module resolution, declaration acquisition, and bad introductory materials (see Angular tutorials), that give developers the wrong impressions about the purpose of the language. Even the Wikipedia page states that TypeScript brings class-based object orientation to JavaScript, so there's a lot of incorrect information out there and when people want to believe something, they find a way... |
Ran into essentially the same scenario today with narrowing union types. Key difference here is that in my case there's no assignment happening, only type guards. If this is a different enough, happy to break it out into its own issue if necessary. type Union = A | B;
type A = { type: "a", isA: boolean };
type B = { type: "b", isB: boolean };
interface Container { union: Union };
interface ContainerNarrowed extends Container {
union: A;
}
declare const container: Container;
if (container.union.type === "a") {
// this is valid, so TS knows that `union` is an `A`
container.union.isA;
// compiler error:
// Type 'Container' is not assignable to type 'ContainerNarrowed'.
// Types of property 'union' are incompatible.
// Type 'Union' is not assignable to type 'A'.
const containerNarrowed: ContainerNarrowed = container;
// it seems as if `container` should satisfy `ContainerNarrowed` here?
} |
I like
--strictNullChecks
options.But this options is very hard to apply existing project.
I want to remove optional operator from interface.
TypeScript 2.0.0 can it! but assignment operation is not under control flow context.
I think we need it.
for example.
or
Off topic.
The text was updated successfully, but these errors were encountered: