Problem description
I have a scenario where I have a function that expects an object of Type T
excluding certain properties of T
.
I have managed to create a Type that exclude specific properties K
from T
without problem (Following this explanation: Exclude property from type)
Now my problem is that Typescript won't give me a type error for when I expect it to, in some scenarios I can still pass an object with properties K
that should be excluded.
Example
I'll provide a small scenario to illustrate:
Take the following types and the given interface:
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
export type DataExclude<T, K extends keyof T> = Partial<Omit<T, K>>
export interface Data {
ID: number,
payload: any,
size: number,
}
Now say I want a function that takes an argument of type Data
excluding "ID"
, I can write:
printDataPartial(partialData: DataExclude<Data,"ID">){
console.log(partialData)
}
Now I expect this function to take an object with any property from Data
except "ID"
(and it doesn't have to be every property, hence the Partial<>
in the DataExclude
type). But it won't accept ID
as a property
Result
Here are some use cases:
partialData: Partial<Data> = {payload: {stuff:'!!!'}, size: 99}
partialDataID: Partial<Data> = {ID:1, payload: {stuff:'???'}, size: 99}
fullData: Data = {ID: 2, payload: {stuff: "..."}, size: 42}
ngOnInit(){
//OK
this.printDataPartial(this.partialData, "Partial Data (no ID): ");
//Not so OK, the partial data has ID in it
this.printDataPartial(this.partialDataID, "Partial Data (with ID): ");
//Not OK, always has ID so should give an error
this.printDataPartial(this.fullData, "Full Data: ");
//OK, gives an error because ID is present
this.printDataPartial({ID: 3, payload: {stuff: "as it comes"}, size: 100}, "Manually typed object (with ID)");
//Not OK, the same with casting
this.printDataPartial(<Data>{ID: 3, payload: {stuff: "as it comes"}, size: 100}, "Manually typed object with casting (with ID): ");
//I know this is an alternative to get a type error early but I'd like to know if there's a way do it differently as the function itself won't give me an error
let partialIncorrect: DataExclude<Data,"ID"> = {ID:4, payload: {stuff:'???'}, size: 99};
this.printDataPartial(partialIncorrect, "Incorrect on initialised: ")
}
I also made a Stackblitz to test easily.
In short, I would like to know if there's a way to get a type error to show up in the editor if the provided argument of the function has ID
in its properties, and I would like to use type safety to do so, not just loop through each property of the given argument manually.