Repository navigation
[Suggestion] Override and identifier! for Mapped Type and extend interface #18567
Description
Activity
can you give us some use cases of each of these requests?
Mohamed Hegazy (@mhegazy)
Case for CRUD db doc//A database doc type, for get interface DocForGet { id: number; //must have id on exist doc, auto generated by db. updatedTime: string | null | undefined; //only have updatedTime if it have been updated (except first create) field1: xxx; ... fieldN: xxx; }
So for
DocForGet:- When you insert a new doc to db,
idis optional, and can't haveupdatedTime. - When you update a doc,
updatedTimemust have a value (can't be null or undefined).
With this request, you can achieve this by:
type DocForInsert = { [P in keyof DocForGet]: DocForGet[P]; // extend id?: DocForInsert[id]; // override id to optional updatedTime?: never; // can't set updatedTime on first create } type DocForUpdate = { [P in keyof DocForGet]: DocForGet[P]; // extend updatedTime: DocForGet[updatedTime]!; //override, identifier! would remove null and undefined }
- When you insert a new doc to db,
- changed the title
[-][Suggestion] Override and identifier! for Mapped Type[/-][+][Suggestion] Override and identifier! for Mapped Type and extend interface[/+]on Sep 20, 2017 The first portion can be defined by using intersection types, (try it on
typescript@next):type DocForInsert = DocForGet & { id?: DocForGet["id"]; // override id to optional updatedTime: never; // force it to be never };
the second part is tracked by #17948.
Assuming that
idandupdatedTimehave the same type across all data types, can you have something like:type Insert<T> = T & { id?: number; updatedTime: never; }; type Get<T> = T & { id: number; updatedTime: string | null | undefined; }; type Update<T> = T & { id: number; updatedTime: string; };
Partion 1, tried on
typescript@2.6.0-dev.20170921, but get error:interface DocForGet { id: number; //must have id on exist doc, auto generated by db. updatedTime: string | null | undefined; //only have updatedTime if it have been updated (except first create) field1: string; } type DocForInsert = DocForGet & { id?: DocForGet["id"]; // override id to optional updatedTime: never; // force it to be never }; let test: DocForInsert = { field1: 'test', }
Error:
test.ts(12,5): error TS2322: Type '{ field1: string; }' is not assignable to type 'DocForInsert'.
Type '{ field1: string; }' is not assignable to type 'DocForGet'.
Property 'id' is missing in type '{ field1: string; }'.You are correct, i was only thinking of the read part of it not the write. for that you need to use
Overwrite.type Diff<T extends string, U extends string> = ({ [P in T]: P } & { [P in U]: never } & { [x: string]: never })[T]; type Omit<T, K extends keyof T> = { [P in Diff<keyof T, K>]: T[P] }; type Overwrite<T, U> = { [P in Diff<keyof T, keyof U>]: T[P] } & U; interface DocForGet { id: number; //must have id on exist doc, auto generated by db. updatedTime: string | null | undefined; //only have updatedTime if it have been updated (except first create) field1: string; } type DocForInsert = Overwrite<DocForGet, { id?: DocForGet["id"]; updatedTime?: never }>; let test: DocForInsert = { field1: 'test', };
Reacted by Danlock- addedQuestionAn issue which isn't directly actionable in codeAn issue which isn't directly actionable in code
on Nov 21, 2017 typescript-bot commented
on Dec 5, 2017 ContributorMore actionsAutomatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.
- locked and limited conversation to collaborators
on Jun 14, 2018
TypeScript Version: 2.4.0 / nightly (2.5.0-dev.201xxxxx)
2.5.2
Situation
There are lots of demand of more flexibility to Mapped Type. For example:
Suggestion
nullandundefined.Code
Benifit
BTW,
function getPropertyin #12578 is a solution, but it cannot be used in declaration files.(.d.ts)