typescript 重写外部定义的类型定义或函数定义

xqkwcwgp  于 2023-05-01  发布在  TypeScript
关注(0)|答案(1)|浏览(154)

我正在做一个文件共享服务。
我有一个名为ValidatedPath的类型,它表示通过validate()函数处理的字符串,该函数检查字符串是否是有效路径。

export type ValidatedPath = string & { __type: "ValidatedPath" };

function validate(path: string): ValidatedPath | null {
    // Severely shortened for clarity
    if(false === regex.test(path)) return null;
    return path as ValidatedPath;
}

问题是,ValidatedPath实际上并不表示文件系统中的实际路径,而只是相对于某个目录的有效路径。
例如:
folder/folder2/file是一个ValidatedPath,但真实的的路径应该是/Users/hello/folder/folder2/file,我将在通过path.join(baseDirectory, validatedPath)调用后获得它
但是,因为ValidatedPath是string的子类型,所以我可以将其传递到文件系统函数中,这将导致错误,因为这不是正确的行为。
例如:

async function rename(original: ValidatedPath, destination: ValidatedPath) {
    await fs.rename(original, destination); // This is allowed, but it's wrong!
    
    const realOriginal: string = path.join(baseDirectory, original);
    const realDestination: string = path.join(baseDirectory, destination);
    await fs.rename(realOriginal, realDestination); // This is correct!
}

解决方案:

我有一些解决方案,我目前不知道如何实施,如果他们甚至可能。

方案一:

文件系统函数接受一个名为PathLike的类型作为参数,该类型在某个node_modules文件中定义。我能以某种方式重写或修改这个外部定义的类型PathLike吗?

// Externally defined
type PathLike = string | Buffer | URL;
function rename(oldPath: PathLike, newPath: PathLike): Promise<void>;
方案二:

我可以让ValidatedPath不是string的子集:

export type ValidatedPath = Omit<string, "toLocaleString">;

这将使它不再有效地将ValidatedPath传递到文件系统函数。但是,这将使它不能与path.join()一起工作,因为它只接受字符串。总是写很烦人,

const realPath = path.join(baseDirectory, validatedPath as string);

但如果我可以修改单个函数路径,它会少得多。join采用string或ValidatedPath,这样就不再需要类型Assert。我能以某种方式覆盖或修改这个外部定义的函数定义path.join吗?
如果以上都不可能,可能只是我被迫使用解决方案2,而不重写path.join,每次我想使用一个接受字符串的函数时,类型AssertValidatedPaths作为字符串。这很烦人,但我可以忍受。我只是觉得一定有更好的解决办法。
先谢谢你了。

rqqzpn5f

rqqzpn5f1#

如果使用多次强制转换让您感到困扰,那么 Package 器函数将是一个解决方案。您可以创建自己的pathJoin函数,该函数接受您的ValidatedPath类型并将其转换为字符串类型,或者使用String函数将其转换为字符串并返回路径的调用。public void run().

function pathJoin(val: ValidatedPath) {
    return path.join(val as string)
}

相关问题