I've been encountering some challenges with TypeScript. Let's say you have a literal object where the value is assigned using the spread operator:
const defaultState = () => {
return {
profile: {
id: '',
displayName: '',
givenName: '',
surName: '',
},
}
}
const state = reactive(defaultState())
const response = await getGraphProfile()
state.profile = { ...defaultState().profile, ...response.data }
After updating the types library @microsoft/microsoft-graph-types
, the following TS error is thrown:
TS2322: Type '{ accountEnabled?: Maybe<boolean>; ageGroup?: string | null | undefined; assignedLicenses?: MicrosoftGraph.AssignedLicense[] | undefined; assignedPlans?: MicrosoftGraph.AssignedPlan[] | undefined; ... 102 more ...; surName: string; }' is not assignable to type '{ id: string; displayName: string; givenName: string; surName: string; jobTitle: string; mail: string; mobilePhone: string; officeLocation: string; businessPhones: string[]; preferredLanguage: string; userPrincipalName: string; }'.
Types of property 'displayName' are incompatible.
Type 'string | null' is not assignable to type 'string'.
Type 'null' is not assignable to type 'string'.
Attempting to set the interface MicrosoftGraph.User
on the literal object as shown in this answer did not resolve it, indicating a possible syntax error:
import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'
const defaultState = () => {
return {
profile: MicrosoftGraph.User = {
id: '',
displayName: '',
givenName: '',
surName: '',
},
}
}
This leads to the TS error below even though the User
interface is present and correctly utilized in the function getGraphProfile
.
TS2339: Property 'User' does not exist on type 'typeof import("T:/Test/Brecht/Node/prod/hip-frontend/node_modules/@microsoft/microsoft-graph-types/microsoft-graph")'.
Additional code:
import config from 'src/app-config.json'
import axios, { AxiosRequestConfig } from 'axios'
import { getToken } from 'src/services/auth/authService'
import * as MicrosoftGraph from '@microsoft/microsoft-graph-types'
const callGraph = <T>(
url: string,
token: string,
axiosConfig?: AxiosRequestConfig
) => {
const params: AxiosRequestConfig = {
method: 'GET',
url: url,
headers: { Authorization: `Bearer ${token}` },
}
return axios.request<T>({ ...params, ...axiosConfig })
}
const getGraphDetails = async <T>(
uri: string,
scopes: string[],
axiosConfig?: AxiosRequestConfig
) => {
try {
const response = await getToken(scopes)
if (response && response.accessToken) {
return callGraph<T>(uri, response.accessToken, axiosConfig)
} else {
throw new Error('We could not get a token because of page redirect')
}
} catch (error) {
throw new Error(`We could not get a token: ${error}`)
}
}
export const getGraphProfile = async () => {
try {
return await getGraphDetails<MicrosoftGraph.User>(
config.resources.msGraphProfile.uri,
config.resources.msGraphProfile.scopes
)
} catch (error) {
throw new Error(`Failed retrieving the graph profile: ${error}`)
}
}
What would be the correct approach to save the property displayName
as string | null
?