TS, derive type from key of another type

Let's say we have this type
type DataFile = {
name: string;
id: number;
category: 'cat' | 'dog'
} | null
type DataFile = {
name: string;
id: number;
category: 'cat' | 'dog'
} | null
and elsewhere I want to have another type:
type DataDisplay = {
name: string;
id: number;
category: ...
}
type DataDisplay = {
name: string;
id: number;
category: ...
}
I want the category of DataDisplay to also be 'cat' | 'dog' but I want to know if there's a way to have it be derived from DataFile so if that changes, the DataDisplay will automatically account for that. like DataFile['category'] but that doesn't work because of the | null
Solution:
sorry, I forgot to actually post the simpler way lmao: ```typescript type DataDisplay = { name: string;...
Jump to solution
5 Replies
Gabriel
Gabriel15mo ago
To achieve this, you can create a type alias for the common properties between DataFile and DataDisplay, and then reuse it in both types. Here's how you can do it:
type CommonData = {
name: string;
id: number;
};

type DataFile = (CommonData & { category: 'cat' | 'dog' }) | null;

type DataDisplay = CommonData & { category: DataFile extends null ? never : DataFile['category'] };
type CommonData = {
name: string;
id: number;
};

type DataFile = (CommonData & { category: 'cat' | 'dog' }) | null;

type DataDisplay = CommonData & { category: DataFile extends null ? never : DataFile['category'] };
In this code, we define a CommonData type alias for the shared properties (name and id). Then, in the DataFile type, we use a union type to represent either the common properties along with the category or null. In the DataDisplay type, we use conditional types to check if DataFile is null. If it is, the category property is set to never, effectively excluding it from DataDisplay. If it's not null, we extract the category from DataFile. This way, if the DataFile type changes, DataDisplay will automatically adjust to it. Here's how you can use these types:
const dataFile: DataFile = { name: 'File 1', id: 1, category: 'cat' };
const dataDisplay: DataDisplay = { name: 'Display 1', id: 2, category: 'dog' };
const dataFile: DataFile = { name: 'File 1', id: 1, category: 'cat' };
const dataDisplay: DataDisplay = { name: 'Display 1', id: 2, category: 'dog' };
If you change the category type in DataFile, it will automatically reflect in DataDisplay.
Donny D
Donny DOP15mo ago
Two things: I think I found a simpler way. And I now realize it won't work, because in the actual thing I'm building for work that I can't share has to factor in translation stuff so the strings 'dog' or 'cat' could ending being different once translated into other values
Gabriel
Gabriel15mo ago
Hi @Donny D I did not even look at your question. I was experimenting to see if the chat gpt answer would fool/satisfy you I just copied and pasted
Gabriel
Gabriel15mo ago
No description
Solution
Donny D
Donny D15mo ago
sorry, I forgot to actually post the simpler way lmao:
type DataDisplay = {
name: string;
id: number;
category: Exclude<DataFile, null>['category']
}
type DataDisplay = {
name: string;
id: number;
category: Exclude<DataFile, null>['category']
}
Want results from more Discord servers?
Add your server