Reputation: 635
I would like to set the type / interface of a variable based on a condition. If possible I would like no reassignment of the variable.
comment1 for below code:
setting the type to responseData: typeA | typeB = response.data
here results in
Errormessage "Property 'specificBValue' does not exist on type 'typeA'.ts(2339)"
or the other way around Property 'specificAValue' does not exist on type 'typeB'
interface typeA {
name: string
specificAValue: number
}
interface typeB {
name: string
specificBValue: string
}
const targetType = userInput.targetType;
axios.get(`/api?target=${targetType}`)
.then(response => {
const responseData = response.data; // comment1
if(targetType === "A") {
responseData: typeA
console.log(responseData.specificAValue);
} else if(targetType === "B") {
responseData: typeB
console.log(responseData.specificBValue);
} else ...
Upvotes: 0
Views: 1017
Reputation: 968
What you need is a way to narrow down the type of responseData
. You can use type guards. See also this.
interface TypeA {
name: string
specificAValue: number
}
interface TypeB {
name: string
specificBValue: string
}
declare const responseData: unknown
const isUnknownRecord = (u: unknown): u is Record<string, unknown> => {
const s = Object.prototype.toString.call(u)
return s === '[object Object]' || s === '[object Window]'
}
const isString = (u: unknown): u is string => typeof u === 'string'
const isNumber = (u: unknown): u is number => typeof u === 'number'
const hasOwnProperty = Object.prototype.hasOwnProperty
const isTypeA = (u: unknown): u is TypeA =>
isUnknownRecord(u) &&
hasOwnProperty.call(u, 'name') &&
isString(u.name) &&
hasOwnProperty.call(u, 'specificAValue') &&
isNumber(u.specificAValue)
const isTypeB = (u: unknown): u is TypeB =>
isUnknownRecord(u) &&
hasOwnProperty.call(u, 'name') &&
isString(u.name) &&
hasOwnProperty.call(u, 'specificBValue') &&
isString(u.specificBValue)
if (isTypeA(responseData)) {
responseData // TypeA
} else if (isTypeB(responseData)) {
responseData // TypeB
}
I suggest you to not reinvent the wheel and use libraries like io-ts.
Upvotes: 1