What I want to achieve:
- A "basic type": Payload, that can be extended by subtypes.
- A method: createPayloadWithData, that takes some data and returns a subtype of payload.
What I have tried:
const createGUID = (): string => {
return "";
};
const callService = (path: string, payload: Payload): void => {
//
};
type Payload = {
id: string;
timeStemp: number;
asyncCall: boolean;
};
function createPayloadWithData<T extends Payload>(
id: string,
asyncCall: boolean,
data?: {}
): T {
let ts = Date.now();
let payload = { id, asyncCall, timeStemp: ts, ...data };
return payload; "//<--- TS error: { id: string; asyncCall: boolean; timeStemp: number; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'Payload
}"
const registerUser = (username: string) => {
const userId = createGUID();
const payload = createPayloadWithData(userId, false, { username });
callService("users", payload);
};
const updateRecords = (records: number[]) => {
const recordsId = createGUID();
const payload = createPayloadWithData(recordsId, true, { records });
callService("records", payload);
};
registerUser("john");
updateRecords([1, 2, 3]);
(In sandbox: https://codesandbox.io/s/ecstatic-bas-97ucu?file=/src/index.ts)
TS throws an error for the return value of createPayloadWithData. Please allow me to say that I know WHY it does not work. I understand the logic and I have read the wonderful explanation here: could be instantiated with a different subtype of constraint 'object'
What I don't understand, is how to do it correctly. Would really appreciate your help. Thanks!
async. I'm surprised it's even allowed. - spender