Why the TransformMap
type has problems with this line [adEnabled ? 'userPrincipalName' : 'krbPrincipalName']: { key: 'loginName' }
? For some reason it can't be inferred the key will be either userPrincipalName
or krbPrincipalName
.
const adEnabled = parseInt(process.env.AD_ENABLED as string, 10);
type TransformMapValues = {
key: string;
transform?: (group: string) => string;
};
interface LdapUserMap {
givenName: TransformMapValues;
sn: TransformMapValues;
mail: TransformMapValues;
memberOf: TransformMapValues;
}
interface OpenLdapUserMap extends LdapUserMap {
krbPrincipalName: TransformMapValues;
}
interface ADUserMap extends LdapUserMap {
userPrincipalName: TransformMapValues;
}
type TransformMap = OpenLdapUserMap | ADUserMap;
const transformMap: TransformMap = {
memberOf: {
key: 'groups',
transform: (group: string) => group.split(',')[0].split('=')[1],
},
mail: { key: 'email' },
givenName: { key: 'firstName' },
sn: { key: 'lastName' },
[adEnabled ? 'userPrincipalName' : 'krbPrincipalName']: { key: 'loginName' },
};
CodePudding user response:
Typescript will only infer named keys from computed keys that are string literal types. Even if the computed keyis a union of string literal types it will fallback to inferring a string index instead of a named key:
const ky = Math.random() ? "k" : "y" // ky: "k" | "y"
const ky = Math.random() ? "k" : "y"
// let x: string = { [x: string]: string; }
let x = { [ky]: "" }
If you use a object spread instead you will get the desired effect:
const transformMap: TransformMap = {
memberOf: {
key: 'groups',
transform: (group: string) => group.split(',')[0].split('=')[1],
},
mail: { key: 'email' },
givenName: { key: 'firstName' },
sn: { key: 'lastName' },
...(adEnabled ? { 'userPrincipalName': { key: 'loginName' } } : { 'krbPrincipalName': { key: 'loginName' }] }),
};