Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/eclipse/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 是否有一种类型安全的方式来表示函数在传递T时返回T类型的对象,但返回Partial类型的对象<;T>;什么时候通过的?_Typescript - Fatal编程技术网

Typescript 是否有一种类型安全的方式来表示函数在传递T时返回T类型的对象,但返回Partial类型的对象<;T>;什么时候通过的?

Typescript 是否有一种类型安全的方式来表示函数在传递T时返回T类型的对象,但返回Partial类型的对象<;T>;什么时候通过的?,typescript,Typescript,我正在编写函数来清理传递给CRUD操作的输入;e、 g.我不希望创建或更新用户的操作能够设置一个指示无限制管理员的内部标志 要做到这一点,我只需使用lodash的\拾取即可从输入中仅投影已知属性: interface IUser { username: string; password: password; } interface IUserInternal { superuser: boolean; } function cleanUser(user: IUser)

我正在编写函数来清理传递给CRUD操作的输入;e、 g.我不希望创建或更新用户的操作能够设置一个指示无限制管理员的内部标志

要做到这一点,我只需使用lodash的
\拾取
即可从输入中仅投影已知属性:

interface IUser {
    username: string;
    password: password;
}

interface IUserInternal {
    superuser: boolean;
}

function cleanUser(user: IUser): IUser {
    return _.pick(user, 'username', 'password');
}

function createUser(user: IUser) {
    db.create(cleanUser(user));
}

function updateUser(id: string, user: Partial<IUser>) {
    const old = db.get(id);
    db.update(id, {...old, ...cleanUser(user)});
}
接口IUser{
用户名:字符串;
密码:密码;
}
内部接口{
超级用户:布尔;
}
函数cleanUser(用户:IUser):IUser{
返回u.pick(用户,'username','password');
}
函数createUser(用户:IUser){
创建(cleanUser(user));
}
函数updateUser(id:字符串,用户:部分){
const old=db.get(id);
update(id,{…old,…cleanUser(user)});
}
我不能依赖于这里的类型检查,因为这是一个服务边界,在添加完整的验证之前,我想暂时坚持一些快速和肮脏的东西

上面的问题在最后一点:显然,我不能在
部分
上调用
cleanUser()
。我也不能让
cleanUser()
获取并返回一个
Partial
,因为这样我会丢失类型检查器,确保我选择了所有属性。实现本身将起作用,因为pick只会跳过在源对象中找不到的属性

我尝试使用签名
cleanUser(user:T):T
来表示我返回的是传入的相同内容,但只是告诉我返回值不能分配给
T
。我尝试添加一个重载签名
cleanUser(user:Partial)
,但是TS即使在传入一个普通用户时也会发现这个签名

是否有一种简洁的方式来表达这一点,或者我只是说“我知道我在做什么”并抑制类型错误?

您可以使用以下方法:

function cleanUser(user: IUser): IUser;
function cleanUser(user: Partial<IUser>): Partial<IUser>;
function cleanUser(user): any {
  return _.pick(user, 'username', 'password');
}
函数cleanUser(用户:IUser):IUser;
函数cleanUser(用户:部分):部分;
函数cleanUser(用户):任意{
返回u.pick(用户,'username','password');
}

我尝试添加一个重载签名cleanUser(user:Partial),但TS即使在传入一个普通用户时也会发现这一点。您的想法是对的,但重载的顺序很重要。TypeScript将匹配它认为合适的第一个签名。换言之,你的满负荷的
IUser
应该排在第一位,然后才是
@KarolMajewski!这导致了一个有趣的情况,我必须为
IUser
添加重载,然后为
Partial
添加重载,然后是实现签名,它与在函数体中获取类型检查的第一个重载相同,但是它完成了任务。我很惊讶TSLint没有抱怨这里有冗余的函数签名。它不是真正的冗余-它告诉编译器一些东西。;-)