我具有以下类型定义:
airbnb = pd.DataFrame({'host_id':[1,1,1,2,2,2],
'reviews_per_month':[4,5,np.nan,9,3,5],
'review_scores_rating':[3,np.nan,np.nan,np.nan,7,8]})
print (airbnb)
host_id review_scores_rating reviews_per_month
0 1 3.0 4.0
1 1 NaN 5.0
2 1 NaN NaN
3 2 NaN 9.0
4 2 7.0 3.0
5 2 8.0 5.0
使用此定义,CountryCodes成功返回以下类型:cols=['reviews_per_month','review_scores_rating'] # would work with all your columns
print (airbnb.fillna(airbnb.groupby('host_id')[cols].transform('mean')))
host_id review_scores_rating reviews_per_month
0 1 3.0 4.0
1 1 3.0 5.0
2 1 3.0 4.5
3 2 7.5 9.0
4 2 7.0 3.0
5 2 8.0 5.0
但是,我想在export const countries = {
US: {
name: "United States"
},
UK: {
name: "United Kingdom"
}
};
export type CountryCodes = keyof typeof countries;
中输入属性值,所以我改用以下类型定义:
"US" | "UK
现在,将countries
的键入定义为export interface IDictionary<T = any> {
[key: string]: T;
}
export interface ICountry {
name: string;
population?: number;
}
export const countries: IDictionary<ICountry> = {
US: {
name: "United States"
},
UK: {
name: "United Kingdom"
}
};
。
如何在保持CountryCode
类型定义的同时,在string | number
结构上获得所需的更强类型?
答案 0 :(得分:2)
通过预先定义密钥
此解决方案要求您预先定义用作字典中键的字符串文字。注意:如果未提供任何参数,则仅将string
用作默认类型参数,而您的IDictionary
的行为将与以前一样。
type IDictionary<V, K extends string = string> = {
[Index in K]: V
}
type CountryCodes = "US" | "UK"
export const countries: IDictionary<ICountry, CountryCodes> = {
US: {
name: "United States"
},
UK: {
name: "United Kingdom"
}
};
通过使用额外的函数调用
在此解决方案中,我们创建了一个工厂函数,以确保我们提供的所有内容都符合特定条件。
const assert = <T>() => <U extends T>(argument: U): U => argument;
用法:
const assertCountries = assert<IDictionary<ICountry>>();
const countries = assertCountries({
US: {
name: "United States"
},
UK: {
name: "United Kingdom"
},
});
type CountryCodes = keyof typeof countries; // "US" | "UK"
通过删除类型定义
有时候,不使用类型定义并信任TypeScript来推断对象文字的类型会更容易。通过这种方法,我们首先从数据开始,并且(如果需要的话)根据您的数据创建类型,就像开始时一样。
为了获得所需的类型安全性,我们将责任转移给您的数据使用者。在这里,foo
确保其自变量符合所需的形状。
const countries = {
US: {
name: "United States"
},
UK: {
name: "United Kingdom"
}
};
type CountryCodes = keyof typeof countries; // "US" | "UK"
function foo<T extends IDictionary<ICountry>>(countries: T): void {
/* ... */
}