[英]Force a function to accept only object of a specific structure (in typescript / js)
I know some of typescript's advantages are enabling type-safe functions -我知道打字稿的一些优点是启用类型安全功能 -
but is it possible to ensure my function can only get objects with specific keys, or in other words - objects of specific structure ?但是是否可以确保我的函数只能获取具有特定键的对象,或者换句话说 - 特定结构的对象?
I know of many elegant ways to test if a nested key exists, such as [this one][1] ,我知道许多优雅的方法来测试嵌套键是否存在,例如 [this one][1] ,
and I can of course run a small check at the beginning of my function - but the reason I'm asking this is because my function will be used by many other programmers - and I want to ensure they can understand what input they should insert just from the function's signature.我当然可以在我的函数的开头运行一个小检查 - 但我问这个的原因是因为我的函数将被许多其他程序员使用 - 我想确保他们能够理解他们应该插入什么输入从函数的签名。
Example:示例:
function printName(user){
console.log(user.details.name); // I want to ensure details.name exist
}
and I would wish to have some feature like:我希望有一些功能,例如:
function (user : {details: {name : string}}){
//same ...
}
[1]: https://stackoverflow.com/questions/2631001/javascript-test-for-existence-of-nested-object-key#answer-4034468 "this one"
interface User {
details:{name: string}
}
function printName(user:User){
console.log(user.details.name); // I want to ensure details.name exist
}
This is exactly the feature you desire:这正是您想要的功能:
function printName(user: { [key: string]: any, details: { [key: string]: any, name: string }}) {
console.log(user.details.name)
}
Allow any properties and require details
+ name
.允许任何属性并需要
details
+ name
。
More legible and protected against unintentional changes:更清晰,并防止意外更改:
// oftentimes you put the following interfaces in extra files:
interface Details {
readonly [key: string]: any // = allow other properties than "name"*
readonly name: string
}
interface User {
readonly [key: string]: any // = allow other properties than "details"*
readonly details: Details
}
// *) consider explicitly specifying them
function printName(user: User) {
console.log(user.details.name)
}
And use the following code if you know other developers may call your function from plain JavaScript code (not TypeScript code):如果您知道其他开发人员可能会从纯 JavaScript 代码(而非 TypeScript 代码)调用您的函数,请使用以下代码:
function printName(user: User) {
const name = ((user || <User>{}).details || <Details>{}).name
if(name == void 0) {
console.error("user name missing")
}
console.log(name)
}
Use keyof if you want to retrieve a value from a specific property, this will highlight the incorrect property name.如果要从特定属性检索值,请使用 keyof,这将突出显示不正确的属性名称。
You can also use Object.keys to check if the property exists.您还可以使用 Object.keys 来检查该属性是否存在。
interface UserProps {
name: string;
age: number;
}
export class User {
constructor(private data: UserProps) {}
get(propName: keyof UserProps): string | number {
const dataKeys = Object.keys(this.data);
if (!dataKeys.includes(propName)) {
throw Error(`Property ${propName} does not exists on user object`);
}
return this.data[propName];
}
}
You can use interfaces in typescript您可以在打字稿中使用接口
export interface Details{
name:string,
age: number
}
export interface User{
details : {
[key: string]: Details
};
}
function printName(user : User){}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.